From c5856b0a68165952e4781cdccc7849c717a16980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 8 Feb 2020 11:47:42 +0200 Subject: [PATCH] MDEV-21351: Allocate aligned memory recv_sys_t::ALIGNMENT: The recv_sys_t::alloc() alignment --- storage/innobase/include/log0recv.h | 3 +++ storage/innobase/log/log0recv.cc | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 0c81a1c0f05..b62c5b77e92 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -365,6 +365,9 @@ public: return true; } + /** The alloc() memory alignment, in bytes */ + static constexpr size_t ALIGNMENT= sizeof(size_t); + /** Get the memory block for storing recv_t and redo log data @param[in] len length of the data to be stored @param[in] store_recv whether to store recv_t object diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index d378638b154..997ccca5fc2 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -892,14 +892,17 @@ inline byte* recv_sys_t::alloc(size_t len, bool store_recv) { create_block: block= buf_block_alloc(nullptr); - block->page.access_time= 1U << 16 | static_cast(len); + block->page.access_time= 1U << 16 | + ut_calc_align(static_cast(len), ALIGNMENT); + static_assert(ut_is_2pow(ALIGNMENT), "ALIGNMENT must be a power of 2"); UT_LIST_ADD_FIRST(blocks, block); UNIV_MEM_INVALID(block->frame, len); UNIV_MEM_FREE(block->frame + len, srv_page_size - len); - return block->frame; + return my_assume_aligned(block->frame); } size_t free_offset= static_cast(block->page.access_time); + ut_ad(!ut_2pow_remainder(free_offset, ALIGNMENT)); if (UNIV_UNLIKELY(!free_offset)) { ut_ad(srv_page_size == 65536); @@ -915,9 +918,9 @@ create_block: goto create_block; block->page.access_time= ((block->page.access_time >> 16) + 1) << 16 | - static_cast(free_offset); + ut_calc_align(static_cast(free_offset), ALIGNMENT); UNIV_MEM_ALLOC(block->frame + free_offset - len, len); - return block->frame + free_offset - len; + return my_assume_aligned(block->frame + free_offset - len); } @@ -925,6 +928,7 @@ create_block: @param data buffer returned by alloc() */ inline void recv_sys_t::free(const void *data) { + ut_ad(!ut_align_offset(data, ALIGNMENT)); data= page_align(data); ut_ad(mutex_own(&mutex)); for (buf_block_t *block= UT_LIST_GET_LAST(blocks);