Skip to content

Commit ac883ac

Browse files
committed
Fix shm_toc.c to always return buffer-aligned memory.
Previously, if you passed a non-aligned size to shm_toc_create(), the memory returned by shm_toc_allocate() would be similarly non-aligned. This was exposed by commit 3cda10f, which allocated structs containing a pg_atomic_uint64 field with shm_toc_allocate(). On systems with MAXIMUM_ALIGNOF = 4, such structs still need to be 8-bytes aligned, but the memory returned by shm_toc_allocate() was only 4-bytes aligned. It's quite bogus that we abuse BUFFERALIGN to align the structs for pg_atomic_uint64. It doesn't really have anything to do with buffers. But that's a separate issue. This ought to fix the buildfarm failures on 32-bit x86 systems. Discussion: https://www.postgresql.org/message-id/7e0a73a5-0df9-1859-b8ae-9acf122dc38d@iki.fi
1 parent 4395f7d commit ac883ac

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

src/backend/storage/ipc/shm_toc.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ shm_toc_create(uint64 magic, void *address, Size nbytes)
4444
Assert(nbytes > offsetof(shm_toc, toc_entry));
4545
toc->toc_magic = magic;
4646
SpinLockInit(&toc->toc_mutex);
47-
toc->toc_total_bytes = nbytes;
47+
48+
/*
49+
* The alignment code in shm_toc_allocate() assumes that the starting
50+
* value is buffer-aligned.
51+
*/
52+
toc->toc_total_bytes = BUFFERALIGN_DOWN(nbytes);
4853
toc->toc_allocated_bytes = 0;
4954
toc->toc_nentry = 0;
5055

@@ -88,7 +93,12 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
8893
Size nentry;
8994
Size toc_bytes;
9095

91-
/* Make sure request is well-aligned. */
96+
/*
97+
* Make sure request is well-aligned. XXX: MAXALIGN is not enough,
98+
* because atomic ops might need a wider alignment. We don't have a
99+
* proper definition for the minimum to make atomic ops safe, but
100+
* BUFFERALIGN ought to be enough.
101+
*/
92102
nbytes = BUFFERALIGN(nbytes);
93103

94104
SpinLockAcquire(&toc->toc_mutex);
@@ -252,7 +262,11 @@ shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
252262
Size
253263
shm_toc_estimate(shm_toc_estimator *e)
254264
{
255-
return add_size(offsetof(shm_toc, toc_entry),
256-
add_size(mul_size(e->number_of_keys, sizeof(shm_toc_entry)),
257-
e->space_for_chunks));
265+
Size sz;
266+
267+
sz = offsetof(shm_toc, toc_entry);
268+
sz += add_size(sz, mul_size(e->number_of_keys, sizeof(shm_toc_entry)));
269+
sz += add_size(sz, e->space_for_chunks);
270+
271+
return BUFFERALIGN(sz);
258272
}

src/include/c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ typedef NameData *Name;
598598
#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN))
599599
#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN))
600600
#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
601+
#define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN))
601602

602603
/*
603604
* The above macros will not work with types wider than uintptr_t, like with

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy