Commit 0cd2e6c6 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-28313: InnoDB transactions are not aligned at cache lines

trx_lock_t: Remove byte pad[256] and use
alignas(CPU_LEVEL1_DCACHE_LINESIZE) instead.

trx_t: Declare n_ref (the first member) aligned at cache line.

Pool: Assert that the sizes are multiples of
CPU_LEVEL1_DCACHE_LINESIZE, and invoke an aligned allocator.
parent f7f0bc74
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......
......@@ -389,7 +389,7 @@ struct trx_lock_t
/** Pre-allocated record locks */
struct {
ib_lock_t lock; byte pad[256];
alignas(CPU_LEVEL1_DCACHE_LINESIZE) ib_lock_t lock;
} rec_pool[8];
/** Pre-allocated table locks */
......@@ -583,6 +583,7 @@ struct trx_t : ilist_node<>
that it is no longer "active".
*/
alignas(CPU_LEVEL1_DCACHE_LINESIZE)
Atomic_counter<int32_t> n_ref;
......@@ -698,7 +699,7 @@ struct trx_t : ilist_node<>
/** The locks of the transaction. Protected by lock_sys.latch
(insertions also by trx_t::mutex). */
trx_lock_t lock;
alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_lock_t lock;
#ifdef WITH_WSREP
/** whether wsrep_on(mysql_thd) held at the start of transaction */
......
/*****************************************************************************
Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2020, MariaDB Corporation.
Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -31,7 +31,7 @@ Created 2012-Feb-26 Sunny Bains
#include <queue>
#include <functional>
#include "ut0new.h"
#include <my_global.h>
/** Allocate the memory for the object in blocks. We keep the objects sorted
on pointer so that they are closer together in case they have to be iterated
......@@ -41,8 +41,6 @@ struct Pool {
typedef Type value_type;
// FIXME: Add an assertion to check alignment and offset is
// as we expect it. Also, sizeof(void*) can be 8, can we impove on this.
struct Element {
Pool* m_pool;
value_type m_type;
......@@ -57,17 +55,30 @@ struct Pool {
m_size(size),
m_last()
{
ut_ad(ut_is_2pow(size));
ut_a(size >= sizeof(Element));
static_assert(!(sizeof(Element) % CPU_LEVEL1_DCACHE_LINESIZE),
"alignment");
m_lock_strategy.create();
ut_a(m_start == 0);
m_start = reinterpret_cast<Element*>(ut_zalloc_nokey(m_size));
#ifdef _MSC_VER
m_start = static_cast<Element*>(
_aligned_malloc(m_size, CPU_LEVEL1_DCACHE_LINESIZE));
#else
void* start;
ut_a(!posix_memalign(&start, CPU_LEVEL1_DCACHE_LINESIZE,
m_size));
m_start = static_cast<Element*>(start);
#endif
memset_aligned<CPU_LEVEL1_DCACHE_LINESIZE>(
m_start, 0, m_size);
m_last = m_start;
m_end = &m_start[m_size / sizeof(*m_start)];
m_end = &m_start[m_size / sizeof *m_start];
/* Note: Initialise only a small subset, even though we have
allocated all the memory. This is required only because PFS
......@@ -90,7 +101,7 @@ struct Pool {
Factory::destroy(&elem->m_type);
}
ut_free(m_start);
IF_WIN(_aligned_free,free)(m_start);
m_end = m_last = m_start = 0;
m_size = 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment