Allocate Backend structs in PostmasterContext.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 9 Oct 2023 08:23:50 +0000 (11:23 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 9 Oct 2023 08:29:39 +0000 (11:29 +0300)
The child processes don't need them. By allocating them in
PostmasterContext, the memory gets free'd and is made available for
other stuff in the child processes.

Reviewed-by: Thomas Munro
Discussion: https://www.postgresql.org/message-id/4f95c1fc-ad3c-7974-3a8c-6faa3931804c@iki.fi

src/backend/postmaster/bgworker.c
src/backend/postmaster/postmaster.c

index 31350d64013cf07065e55f61bf5fb86dc50e24b5..cc66c61dee792c52d2482a927c1f52b2274670f8 100644 (file)
@@ -33,6 +33,7 @@
 #include "storage/shmem.h"
 #include "tcop/tcopprot.h"
 #include "utils/ascii.h"
+#include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/timeout.h"
 
@@ -347,7 +348,9 @@ BackgroundWorkerStateChange(bool allow_new_workers)
        /*
         * Copy the registration data into the registered workers list.
         */
-       rw = malloc(sizeof(RegisteredBgWorker));
+       rw = MemoryContextAllocExtended(PostmasterContext,
+                                       sizeof(RegisteredBgWorker),
+                                       MCXT_ALLOC_NO_OOM);
        if (rw == NULL)
        {
            ereport(LOG,
@@ -455,7 +458,7 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
                             rw->rw_worker.bgw_name)));
 
    slist_delete_current(cur);
-   free(rw);
+   pfree(rw);
 }
 
 /*
@@ -951,7 +954,9 @@ RegisterBackgroundWorker(BackgroundWorker *worker)
    /*
     * Copy the registration data into the registered workers list.
     */
-   rw = malloc(sizeof(RegisteredBgWorker));
+   rw = MemoryContextAllocExtended(PostmasterContext,
+                                   sizeof(RegisteredBgWorker),
+                                   MCXT_ALLOC_NO_OOM);
    if (rw == NULL)
    {
        ereport(LOG,
index bc3c992a3a3c443876b1052dccfd3ee327323e79..583c9b03246352dd5515848a865c28a70550088b 100644 (file)
@@ -3321,7 +3321,7 @@ CleanupBackgroundWorker(int pid,
         */
        if (rw->rw_backend->bgworker_notify)
            BackgroundWorkerStopNotifications(rw->rw_pid);
-       free(rw->rw_backend);
+       pfree(rw->rw_backend);
        rw->rw_backend = NULL;
        rw->rw_pid = 0;
        rw->rw_child_slot = 0;
@@ -3414,7 +3414,7 @@ CleanupBackend(int pid,
                BackgroundWorkerStopNotifications(bp->pid);
            }
            dlist_delete(iter.cur);
-           free(bp);
+           pfree(bp);
            break;
        }
    }
@@ -3470,7 +3470,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 #ifdef EXEC_BACKEND
            ShmemBackendArrayRemove(rw->rw_backend);
 #endif
-           free(rw->rw_backend);
+           pfree(rw->rw_backend);
            rw->rw_backend = NULL;
            rw->rw_pid = 0;
            rw->rw_child_slot = 0;
@@ -3507,7 +3507,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 #endif
            }
            dlist_delete(iter.cur);
-           free(bp);
+           pfree(bp);
            /* Keep looping so we can signal remaining backends */
        }
        else
@@ -4083,7 +4083,7 @@ BackendStartup(Port *port)
     * Create backend data structure.  Better before the fork() so we can
     * handle failure cleanly.
     */
-   bn = (Backend *) malloc(sizeof(Backend));
+   bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
    if (!bn)
    {
        ereport(LOG,
@@ -4099,7 +4099,7 @@ BackendStartup(Port *port)
     */
    if (!RandomCancelKey(&MyCancelKey))
    {
-       free(bn);
+       pfree(bn);
        ereport(LOG,
                (errcode(ERRCODE_INTERNAL_ERROR),
                 errmsg("could not generate random cancel key")));
@@ -4129,8 +4129,6 @@ BackendStartup(Port *port)
    pid = fork_process();
    if (pid == 0)               /* child */
    {
-       free(bn);
-
        /* Detangle from postmaster */
        InitPostmasterChild();
 
@@ -4161,7 +4159,7 @@ BackendStartup(Port *port)
 
        if (!bn->dead_end)
            (void) ReleasePostmasterChildSlot(bn->child_slot);
-       free(bn);
+       pfree(bn);
        errno = save_errno;
        ereport(LOG,
                (errmsg("could not fork new process for connection: %m")));
@@ -5424,7 +5422,7 @@ StartAutovacuumWorker(void)
            return;
        }
 
-       bn = (Backend *) malloc(sizeof(Backend));
+       bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
        if (bn)
        {
            bn->cancel_key = MyCancelKey;
@@ -5451,7 +5449,7 @@ StartAutovacuumWorker(void)
             * logged by StartAutoVacWorker
             */
            (void) ReleasePostmasterChildSlot(bn->child_slot);
-           free(bn);
+           pfree(bn);
        }
        else
            ereport(LOG,
@@ -5696,7 +5694,7 @@ do_start_bgworker(RegisteredBgWorker *rw)
            /* undo what assign_backendlist_entry did */
            ReleasePostmasterChildSlot(rw->rw_child_slot);
            rw->rw_child_slot = 0;
-           free(rw->rw_backend);
+           pfree(rw->rw_backend);
            rw->rw_backend = NULL;
            /* mark entry as crashed, so we'll try again later */
            rw->rw_crashed_at = GetCurrentTimestamp();
@@ -5822,7 +5820,7 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
        return false;
    }
 
-   bn = malloc(sizeof(Backend));
+   bn = palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
    if (bn == NULL)
    {
        ereport(LOG,