Skip to content
Snippets Groups Projects
Commit ccfef5fd authored by Vladimir Davydov's avatar Vladimir Davydov Committed by Vladimir Davydov
Browse files

memtx: ignore slab_alloc_granularity < machine word size

box.cfg.slab_alloc_granularity sets the min alignment used for struct
memtx_tuple. By default, it's set to the machine word size (8 bytes
typically), but it can be set to 4 bytes to reduce memory usage.

The problem is that we add memtx tuples to a garbage collection list
using the intrusive list pattern (basically, store a pointer to the next
entry in the first 8 bytes of the `memtx_tuple` struct). If
`box.cfg.slab_alloc_factor` is set to 4, the pointer will be unaligned
while the compiler will generate the machine code assuming it is
naturally aligned. For some architectures (x86), this works fine, but
for others (ARM), this may result in a runtime failure.

To fix this issue, we need to instruct the compiler that the list
pointer stored in `memtx_tuple` may be unaligned.

For now, let's silently ignore granularity < the machine word size,
because we're planning to switch from lifo to stailq for memtx garbage
collection lists, which would result in explicit compiler warnings.

See #7422
Needed for #7185

NO_DOC=invisible to the user
NO_CHANGELOG=invisible to the user
NO_TEST=will be added later when the bug is fixed
parent 0aab49f0
No related branches found
No related tags found
No related merge requests found
...@@ -32,7 +32,12 @@ ...@@ -32,7 +32,12 @@
#include "allocator.h" #include "allocator.h"
#include "tuple.h" #include "tuple.h"
struct PACKED memtx_tuple { /**
* Memtx tuple sub-class.
*
* FIXME(gh-7422): Make this struct packed.
*/
struct memtx_tuple {
/* /*
* sic: the header of the tuple is used * sic: the header of the tuple is used
* to store a free list pointer in smfree_delayed. * to store a free list pointer in smfree_delayed.
......
...@@ -1241,6 +1241,16 @@ memtx_engine_new(const char *snap_dirname, bool force_recovery, ...@@ -1241,6 +1241,16 @@ memtx_engine_new(const char *snap_dirname, bool force_recovery,
bool dontdump, unsigned granularity, bool dontdump, unsigned granularity,
const char *allocator, float alloc_factor) const char *allocator, float alloc_factor)
{ {
/*
* FIXME(gh-7422): We use the intrusive list pattern to organize memtx
* tuples into a garbage collection list during snapshotting. Setting
* the granularity to a value less than the machine word size can thus
* result in unaligned pointer dereference, which may fail on certain
* architectures. So we silently overwrite the granularity if it's less
* than the machine word size.
*/
granularity = MAX(granularity, sizeof(void *));
int64_t snap_signature; int64_t snap_signature;
struct memtx_engine *memtx = struct memtx_engine *memtx =
(struct memtx_engine *)calloc(1, sizeof(*memtx)); (struct memtx_engine *)calloc(1, sizeof(*memtx));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment