Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions contrib/pgcrypto/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ px_find_digest(const char *name, PX_MD **res)
* The order is crucial, to make sure we don't leak anything on
* out-of-memory or other error.
*/
digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
digest = palloc(sizeof(*digest));

ctx = EVP_MD_CTX_create();
if (!ctx)
Expand All @@ -196,7 +196,6 @@ px_find_digest(const char *name, PX_MD **res)
digest->owner = CurrentResourceOwner;
ResourceOwnerRememberOSSLDigest(digest->owner, digest);

/* The PX_MD object is allocated in the current memory context. */
h = palloc_object(PX_MD);
h->result_size = digest_result_size;
h->block_size = digest_block_size;
Expand Down Expand Up @@ -794,7 +793,7 @@ px_find_cipher(const char *name, PX_Cipher **res)
* The order is crucial, to make sure we don't leak anything on
* out-of-memory or other error.
*/
od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
od = palloc0(sizeof(*od));
od->ciph = i->ciph;

/* Allocate an EVP_CIPHER_CTX object. */
Expand All @@ -812,7 +811,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
if (i->ciph->cipher_func)
od->evp_ciph = i->ciph->cipher_func();

/* The PX_Cipher is allocated in current memory context */
c = palloc_object(PX_Cipher);
c->block_size = gen_ossl_block_size;
c->key_size = gen_ossl_key_size;
Expand Down
24 changes: 24 additions & 0 deletions src/backend/access/transam/xact.c
Original file line number Diff line number Diff line change
Expand Up @@ -3000,6 +3000,15 @@ AbortTransaction(void)
ResourceOwnerRelease(TopTransactionResourceOwner,
RESOURCE_RELEASE_AFTER_LOCKS,
false, true);

/*
* Now that resource owner cleanup has finished, we can release the
* memory resource owners might have still accessed during cleanup.
*
* Note the portal context itself is freed later in PortalDrop.
*/
AtAbort_Portals_ReleaseMemory();

smgrDoPendingDeletes(false);

AtEOXact_GUC(false, 1);
Expand All @@ -3017,6 +3026,10 @@ AbortTransaction(void)
AtEOXact_LogicalCtl();
pgstat_report_xact_timestamp(0);
}
else
{
AtAbort_Portals_ReleaseMemory();
}

/*
* State remains TRANS_ABORT until CleanupTransaction().
Expand Down Expand Up @@ -4939,6 +4952,7 @@ AbortOutOfAnyTransaction(void)
* we need to shut down before doing CleanupTransaction.
*/
AtAbort_Portals();
AtAbort_Portals_ReleaseMemory();
CleanupTransaction();
s->blockState = TBLOCK_DEFAULT;
break;
Expand Down Expand Up @@ -4968,6 +4982,7 @@ AbortOutOfAnyTransaction(void)
s->parent->subTransactionId,
s->curTransactionOwner,
s->parent->curTransactionOwner);
AtSubAbort_Portals_ReleaseMemory(s->subTransactionId);
}
CleanupSubTransaction();
s = CurrentTransactionState; /* changed by pop */
Expand Down Expand Up @@ -5371,6 +5386,15 @@ AbortSubTransaction(void)
ResourceOwnerRelease(s->curTransactionOwner,
RESOURCE_RELEASE_AFTER_LOCKS,
false, false);

/*
* Now that resource owner cleanup has finished, we can release the
* memory resource owners might have still accessed during cleanup.
*
* Note the portal context itself is freed later in PortalDrop.
*/
AtSubAbort_Portals_ReleaseMemory(s->subTransactionId);

AtSubAbort_smgr();

AtEOXact_GUC(false, s->gucNestLevel);
Expand Down
14 changes: 9 additions & 5 deletions src/backend/jit/llvm/llvmjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ llvm_create_context(int jitFlags)

ResourceOwnerEnlarge(CurrentResourceOwner);

context = MemoryContextAllocZero(TopMemoryContext,
sizeof(LLVMJitContext));
context = palloc0(sizeof(LLVMJitContext));
context->base.flags = jitFlags;

/* ensure cleanup */
Expand Down Expand Up @@ -760,8 +759,13 @@ llvm_compile_module(LLVMJitContext *context)
pfree(filename);
}

/*
* Allocate handle in the same long-lived context as the LLVMJitContext,
* since this can be called during expression evaluation in a short-lived
* per-tuple context.
*/
handle = (LLVMJitHandle *)
MemoryContextAlloc(TopMemoryContext, sizeof(LLVMJitHandle));
MemoryContextAlloc(GetMemoryChunkContext(context), sizeof(LLVMJitHandle));

/*
* Emit the code. Note that this can, depending on the optimization
Expand Down Expand Up @@ -805,8 +809,8 @@ llvm_compile_module(LLVMJitContext *context)
context->module = NULL;
context->compiled = true;

/* remember emitted code for cleanup and lookups */
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
/* remember emitted code for cleanup and lookups. */
oldcontext = MemoryContextSwitchTo(GetMemoryChunkContext(context));
context->handles = lappend(context->handles, handle);
MemoryContextSwitchTo(oldcontext);

Expand Down
9 changes: 7 additions & 2 deletions src/backend/storage/ipc/waiteventset.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,14 @@ CreateWaitEventSet(ResourceOwner resowner, int nevents)
#endif

if (resowner != NULL)
{
ResourceOwnerEnlarge(resowner);

data = (char *) MemoryContextAllocZero(TopMemoryContext, sz);
data = (char *) palloc0(sz);
}
else
{
data = (char *) MemoryContextAllocZero(TopMemoryContext, sz);
}

set = (WaitEventSet *) data;
data += MAXALIGN(sizeof(WaitEventSet));
Expand Down
60 changes: 56 additions & 4 deletions src/backend/utils/mmgr/portalmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,40 @@ AtAbort_Portals(void)
* PortalDrop.
*/
portal->resowner = NULL;
}
}

/*
* Release subsidiary memory for aborted portals.
*
* This is called after ResourceOwnerRelease, so that any resources still
* referencing portal memory have been cleaned up first.
*/
void
AtAbort_Portals_ReleaseMemory(void)
{
HASH_SEQ_STATUS status;
PortalHashEnt *hentry;

hash_seq_init(&status, PortalHashTable);

while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
{
Portal portal = hentry->portal;

/* Do nothing to cursors held over from a previous transaction. */
if (portal->createSubid == InvalidSubTransactionId)
continue;

/* Do nothing to auto-held cursors. */
if (portal->autoHeld)
continue;

/*
* Although we can't delete the portal data structure proper, we can
* release any memory in subsidiary contexts, such as executor state.
* The cleanup hook was the last thing that might have needed data
* there. But leave active portals alone.
* The portal cleanup hook or ResourceOwnerRelease were the last thing
* that might have needed data there. But leave active portals alone.
*/
if (portal->status != PORTAL_ACTIVE)
MemoryContextDeleteChildren(portal->portalContext);
Expand Down Expand Up @@ -1074,11 +1102,35 @@ AtSubAbort_Portals(SubTransactionId mySubid,
*/
portal->resowner = NULL;

}
}

/*
* Release subsidiary memory for portals aborted in a subtransaction.
*
* This is called after ResourceOwnerRelease, so that any resources still
* referencing portal memory have been cleaned up first.
*/
void
AtSubAbort_Portals_ReleaseMemory(SubTransactionId mySubid)
{
HASH_SEQ_STATUS status;
PortalHashEnt *hentry;

hash_seq_init(&status, PortalHashTable);

while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
{
Portal portal = hentry->portal;

if (portal->createSubid != mySubid)
continue;

/*
* Although we can't delete the portal data structure proper, we can
* release any memory in subsidiary contexts, such as executor state.
* The cleanup hook was the last thing that might have needed data
* there.
* The portal cleanup hook or ResourceOwnerRelease were the last thing
* that might have needed data there.
*/
MemoryContextDeleteChildren(portal->portalContext);
}
Expand Down
7 changes: 3 additions & 4 deletions src/common/cryptohash_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@
#endif

/*
* In the backend, use an allocation in TopMemoryContext to count for
* resowner cleanup handling. In the frontend, use malloc to be able
* to return a failure status back to the caller.
* In backends, use an allocation in the current memory context. In frontend,
* use malloc to be able to return a failure status back to the caller.
*/
#ifndef FRONTEND
#define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size)
#define ALLOC(size) palloc(size)
#define FREE(ptr) pfree(ptr)
#else
#define ALLOC(size) malloc(size)
Expand Down
7 changes: 3 additions & 4 deletions src/common/hmac_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@
#endif

/*
* In backend, use an allocation in TopMemoryContext to count for resowner
* cleanup handling if necessary. In frontend, use malloc to be able to return
* a failure status back to the caller.
* In backends, use an allocation in the current memory context. In frontend,
* use malloc to be able to return a failure status back to the caller.
*/
#ifndef FRONTEND
#define USE_RESOWNER_FOR_HMAC
#define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size)
#define ALLOC(size) palloc(size)
#define FREE(ptr) pfree(ptr)
#else /* FRONTEND */
#define ALLOC(size) malloc(size)
Expand Down
2 changes: 2 additions & 0 deletions src/include/utils/portal.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ typedef struct PortalData
extern void EnablePortalManager(void);
extern bool PreCommit_Portals(bool isPrepare);
extern void AtAbort_Portals(void);
extern void AtAbort_Portals_ReleaseMemory(void);
extern void AtCleanup_Portals(void);
extern void PortalErrorCleanup(void);
extern void AtSubCommit_Portals(SubTransactionId mySubid,
Expand All @@ -225,6 +226,7 @@ extern void AtSubAbort_Portals(SubTransactionId mySubid,
SubTransactionId parentSubid,
ResourceOwner myXactOwner,
ResourceOwner parentXactOwner);
extern void AtSubAbort_Portals_ReleaseMemory(SubTransactionId mySubid);
extern void AtSubCleanup_Portals(SubTransactionId mySubid);
extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
extern Portal CreateNewPortal(void);
Expand Down