mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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 3cda10f41b, 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
This commit is contained in:
		
							parent
							
								
									4395f7daf3
								
							
						
					
					
						commit
						ac883ac453
					
				| @ -44,7 +44,12 @@ shm_toc_create(uint64 magic, void *address, Size nbytes) | ||||
| 	Assert(nbytes > offsetof(shm_toc, toc_entry)); | ||||
| 	toc->toc_magic = magic; | ||||
| 	SpinLockInit(&toc->toc_mutex); | ||||
| 	toc->toc_total_bytes = nbytes; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The alignment code in shm_toc_allocate() assumes that the starting | ||||
| 	 * value is buffer-aligned. | ||||
| 	 */ | ||||
| 	toc->toc_total_bytes = BUFFERALIGN_DOWN(nbytes); | ||||
| 	toc->toc_allocated_bytes = 0; | ||||
| 	toc->toc_nentry = 0; | ||||
| 
 | ||||
| @ -88,7 +93,12 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) | ||||
| 	Size		nentry; | ||||
| 	Size		toc_bytes; | ||||
| 
 | ||||
| 	/* Make sure request is well-aligned. */ | ||||
| 	/*
 | ||||
| 	 * Make sure request is well-aligned.  XXX: MAXALIGN is not enough, | ||||
| 	 * because atomic ops might need a wider alignment.  We don't have a | ||||
| 	 * proper definition for the minimum to make atomic ops safe, but | ||||
| 	 * BUFFERALIGN ought to be enough. | ||||
| 	 */ | ||||
| 	nbytes = BUFFERALIGN(nbytes); | ||||
| 
 | ||||
| 	SpinLockAcquire(&toc->toc_mutex); | ||||
| @ -252,7 +262,11 @@ shm_toc_lookup(shm_toc *toc, uint64 key, bool noError) | ||||
| Size | ||||
| shm_toc_estimate(shm_toc_estimator *e) | ||||
| { | ||||
| 	return add_size(offsetof(shm_toc, toc_entry), | ||||
| 					add_size(mul_size(e->number_of_keys, sizeof(shm_toc_entry)), | ||||
| 							 e->space_for_chunks)); | ||||
| 	Size		sz; | ||||
| 
 | ||||
| 	sz = offsetof(shm_toc, toc_entry); | ||||
| 	sz += add_size(sz, mul_size(e->number_of_keys, sizeof(shm_toc_entry))); | ||||
| 	sz += add_size(sz, e->space_for_chunks); | ||||
| 
 | ||||
| 	return BUFFERALIGN(sz); | ||||
| } | ||||
|  | ||||
| @ -598,6 +598,7 @@ typedef NameData *Name; | ||||
| #define LONGALIGN_DOWN(LEN)		TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN)) | ||||
| #define DOUBLEALIGN_DOWN(LEN)	TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) | ||||
| #define MAXALIGN_DOWN(LEN)		TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) | ||||
| #define BUFFERALIGN_DOWN(LEN)	TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN)) | ||||
| 
 | ||||
| /*
 | ||||
|  * The above macros will not work with types wider than uintptr_t, like with | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user