diff options
author | Thomas Munro <tmunro@postgresql.org> | 2020-02-01 14:29:13 +1300 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2020-02-01 14:49:57 +1300 |
commit | 24dd34af1435a2a97e8b67d82328e45d0ac51413 (patch) | |
tree | 3b2cbd807e5cc9f426f23e2030a36aefb6cdfebd /src | |
parent | 65aa155135a5c7c913bcb042c51d72eaad53582f (diff) | |
download | postgresql-24dd34af1435a2a97e8b67d82328e45d0ac51413.tar.gz postgresql-24dd34af1435a2a97e8b67d82328e45d0ac51413.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.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 142293fd2c3..9bf16de9407 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"))); |