summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2020-02-01 01:29:13 +0000
committerThomas Munro2020-02-01 02:10:20 +0000
commit95936c795b9f086c2b413b5150d2993ac30354fa (patch)
treefbc595dd13db42f9d207aa386bc84f23988b6254
parentf521ef0ae3199ed2d16fc11a865738f7fe54f38b (diff)
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
-rw-r--r--src/backend/storage/ipc/dsm.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 0e5a0c399f..ed0b1f15f7 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -496,9 +496,18 @@ dsm_create(Size size)
/* 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);
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("too many dynamic shared memory segments")));
+ }
/* Enter the handle into a new array slot. */
dsm_control->item[nitems].handle = seg->handle;