Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d5ee4db

Browse files
committed
Use MAXALIGN() in calculations using sizeof(SlabBlock)
c6e0fe1 added a new pointer field to SlabBlock to make it 4 bytes larger on 32-bit machines. Prior to that commit, the size of that struct was a multiple of 8, which meant that MAXALIGN(sizeof(SlabBlock)) was the same as sizeof(SlabBlock), however, after c6e0fe1, due to the addition of the new pointer field to store a pointer to the owning context, that was no longer true on builds with sizeof(void *) == 4. This problem was highlighted by an Assert failure which was checking that the pointer given to pfree() was MAXALIGNED. Various 32-bit ARM buildfarm animals were failing. These have MAXIMUM_ALIGNOF of 8. The only 32-bit testing I'd managed to do on c6e0fe1 had been on x86, which has a MAXIMUM_ALIGNOF of 4, therefore did not exhibit this issue. Here we define Slab_BLOCKHDRSZ and copy what is being done in aset.c and generation.c for doing calculations based on the size of the context's block type. This means that SlabAlloc() will now always return a MAXALIGNed pointer. This also fixes an incorrect sentinel_ok() check in SlabCheck() which was incorrectly checking the wrong sentinel byte. This must have previously not caused any issues due to the fullChunkSize never being large enough to store the sentinel byte. Diagnosed-by: Tomas Vondra, Tom Lane Author: Tomas Vondra, David Rowley Discussion: https://postgr.es/m/CAA4eK1%2B1JyW5TiL%3DyV-3Uq1CrfnTyn0Xrk5uArt31Z%3D8rgPhXQ%40mail.gmail.com
1 parent b1ec7f4 commit d5ee4db

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/backend/utils/mmgr/slab.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
#include "utils/memutils_memorychunk.h"
5959
#include "utils/memutils_internal.h"
6060

61+
#define Slab_BLOCKHDRSZ MAXALIGN(sizeof(SlabBlock))
62+
6163
/*
6264
* SlabContext is a specialized implementation of MemoryContext.
6365
*/
@@ -102,10 +104,10 @@ typedef struct SlabBlock
102104
#define SlabChunkGetPointer(chk) \
103105
((void *)(((char *)(chk)) + sizeof(MemoryChunk)))
104106
#define SlabBlockGetChunk(slab, block, idx) \
105-
((MemoryChunk *) ((char *) (block) + sizeof(SlabBlock) \
107+
((MemoryChunk *) ((char *) (block) + Slab_BLOCKHDRSZ \
106108
+ (idx * slab->fullChunkSize)))
107109
#define SlabBlockStart(block) \
108-
((char *) block + sizeof(SlabBlock))
110+
((char *) block + Slab_BLOCKHDRSZ)
109111
#define SlabChunkIndex(slab, block, chunk) \
110112
(((char *) chunk - SlabBlockStart(block)) / slab->fullChunkSize)
111113

@@ -146,12 +148,12 @@ SlabContextCreate(MemoryContext parent,
146148
fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize);
147149

148150
/* Make sure the block can store at least one chunk. */
149-
if (blockSize < fullChunkSize + sizeof(SlabBlock))
151+
if (blockSize < fullChunkSize + Slab_BLOCKHDRSZ)
150152
elog(ERROR, "block size %zu for slab is too small for %zu chunks",
151153
blockSize, chunkSize);
152154

153155
/* Compute maximum number of chunks per block */
154-
chunksPerBlock = (blockSize - sizeof(SlabBlock)) / fullChunkSize;
156+
chunksPerBlock = (blockSize - Slab_BLOCKHDRSZ) / fullChunkSize;
155157

156158
/* The freelist starts with 0, ends with chunksPerBlock. */
157159
freelistSize = sizeof(dlist_head) * (chunksPerBlock + 1);
@@ -744,7 +746,7 @@ SlabCheck(MemoryContext context)
744746

745747
/* there might be sentinel (thanks to alignment) */
746748
if (slab->chunkSize < (slab->fullChunkSize - Slab_CHUNKHDRSZ))
747-
if (!sentinel_ok(chunk, slab->chunkSize))
749+
if (!sentinel_ok(chunk, Slab_CHUNKHDRSZ + slab->chunkSize))
748750
elog(WARNING, "problem in slab %s: detected write past chunk end in block %p, chunk %p",
749751
name, block, chunk);
750752
}

0 commit comments

Comments
 (0)