From 0755ba81037e0ad5a9af7f94d960c0f9ce199848 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 30 Jan 2020 20:48:41 +1300 Subject: [PATCH] Fix memory leak on DSM slot exhaustion. If you try to create a DSM segment but 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.5, where DSM segments arrived. Reported-by: Julian Backes Discussion: https://postgr.es/m/CA%2BhUKG%2Bzw87b70yJp%2BOzz6LqS6s9QvdO4%2BhQuZc%3DDWLMi6Od6A%40mail.gmail.com --- src/backend/storage/ipc/dsm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 90e0d739f8..aef643516a 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -484,17 +484,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"))); -- 2.23.0