aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2020-02-01 14:29:13 +1300
committerThomas Munro <tmunro@postgresql.org>2020-02-01 22:57:46 +1300
commit600387f5dd286d6ca72a578b09ef3765f45d95e6 (patch)
tree8efba0ef9dc7e2c4cb81f1bc07a69c98a599e693 /src
parent25dc267a1be573c36c4e40dce651ae462f17eb9e (diff)
downloadpostgresql-600387f5dd286d6ca72a578b09ef3765f45d95e6.tar.gz
postgresql-600387f5dd286d6ca72a578b09ef3765f45d95e6.zip
Fix memory leak on DSM slot exhaustion.
If we attempt to create a DSM segment when no slots are available, we should return the memory to the operating system. Previously we did that if the DSM_CREATE_NULL_IF_MAXSEGMENTS flag was passed in, but we didn't do it if an error was raised. Repair. Back-patch to 9.4, where DSM segments arrived. Author: Thomas Munro Reviewed-by: Robert Haas Reported-by: Julian Backes Discussion: https://postgr.es/m/CA%2BhUKGKAAoEw-R4om0d2YM4eqT1eGEi6%3DQot-3ceDR-SLiWVDw%40mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/dsm.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index ef509d99b5d..df2e31486fa 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -499,17 +499,16 @@ dsm_create(Size size, int flags)
/* Verify that we can support an additional mapping. */
if (nitems >= dsm_control->maxitems)
{
+ LWLockRelease(DynamicSharedMemoryControlLock);
+ dsm_impl_op(DSM_OP_DESTROY, seg->handle, 0, &seg->impl_private,
+ &seg->mapped_address, &seg->mapped_size, WARNING);
+ if (seg->resowner != NULL)
+ ResourceOwnerForgetDSM(seg->resowner, seg);
+ dlist_delete(&seg->node);
+ pfree(seg);
+
if ((flags & DSM_CREATE_NULL_IF_MAXSEGMENTS) != 0)
- {
- LWLockRelease(DynamicSharedMemoryControlLock);
- dsm_impl_op(DSM_OP_DESTROY, seg->handle, 0, &seg->impl_private,
- &seg->mapped_address, &seg->mapped_size, WARNING);
- if (seg->resowner != NULL)
- ResourceOwnerForgetDSM(seg->resowner, seg);
- dlist_delete(&seg->node);
- pfree(seg);
return NULL;
- }
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("too many dynamic shared memory segments")));