Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qWMnh-0031m4-0V for pgsql-hackers@arkaria.postgresql.org; Wed, 16 Aug 2023 20:07:29 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qWMnd-009R81-97 for pgsql-hackers@arkaria.postgresql.org; Wed, 16 Aug 2023 20:07:25 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qWMnc-009R7t-Tx for pgsql-hackers@lists.postgresql.org; Wed, 16 Aug 2023 20:07:25 +0000 Received: from mail-oi1-x229.google.com ([2607:f8b0:4864:20::229]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qWMnZ-000Ww7-Es for pgsql-hackers@postgresql.org; Wed, 16 Aug 2023 20:07:24 +0000 Received: by mail-oi1-x229.google.com with SMTP id 5614622812f47-3a5a7e7cd61so137341b6e.0 for ; Wed, 16 Aug 2023 13:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692216439; x=1692821239; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=vpA1gx7kCLrN2OMKJmLpFQwpFjOGyBAjrUWFcj7eS6U=; b=WsIlBc0UqvWW21avArQDJ7SO3rzpdu3JH0PcPHEW895Xr5BNOatnmhulZ+jpX5CDwu CKm857+Gff5o9gnVMXiw/Bjs2jZ1GdcWvYkrCNGladDNCYPcELWaKhg9cJWN64tuUSNX yZJ4sFzzzqKwN91nhuy7cBcnSjinC7a7zZgvOwZzs/NkbZEEbySMei77NL2jSj7wAHbc Ywhx/hK0VLn3WotDz0hzZdSZN2JC70vytKQqtXeOOBIQ+uU8oxnCfaPzH9zF+Wjs/bTh tmxPKw7GUK5DPzADIAB7aYpmGOfWreAHPlleKbVsgJP4CRq9zeagu3pSs+XMj4fZqJI5 SoWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692216439; x=1692821239; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=vpA1gx7kCLrN2OMKJmLpFQwpFjOGyBAjrUWFcj7eS6U=; b=GX6RjVBffVstl+qBHZT2h872BhESVyiQQx+fZK11a6e8q5HSDBGJIODOM+gPleEKLM 8oB1lLdrHU87jw7PiO/oI9RfttMkExHOaA4hVIPo1V+4Qh51p0QzZSEPVry5GAAAlNcs 5jIl0rNpSoEV6ST7ClWzzzyfP5D4C5mooRXSEmXK0GcgUGR5AD2XyGURy/5NLumlRpiC 9dEHNWRANUhN/sBRfU5qQRWxyKK3ceUFmjn1N4zJsMBCkmDfzUTBORJTGqiGUD31nq5T b82idh84UPv8/VbHKBBvaVAo/17Idpq18qswIIdM0HBfrN8YnJJeV/ZL7IIoDO6cYFOD tTPw== X-Gm-Message-State: AOJu0YzJVDz1fXdhqDr2PD5x0zHhzoNUahVS6tl6K4NvZ9tlyBjq+KPY XzAKkm1b7rjgX467aRUp0u8= X-Google-Smtp-Source: AGHT+IF2GNS1PdmEI/uFIIWRWAX1xldHTpvbhlmgdYcWgrd8zpzpdDP7HdrCyGeBIbhkctJ7wPnZoA== X-Received: by 2002:a05:6808:1b22:b0:3a4:4993:eef9 with SMTP id bx34-20020a0568081b2200b003a44993eef9mr491852oib.28.1692216439176; Wed, 16 Aug 2023 13:07:19 -0700 (PDT) Received: from nathanxps13 ([2600:1700:48f8:340f:ff08:b852:b3e6:dbaa]) by smtp.gmail.com with ESMTPSA id bh20-20020a056808181400b003a3fd014ccasm6877354oib.9.2023.08.16.13.07.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 13:07:18 -0700 (PDT) Date: Wed, 16 Aug 2023 13:07:15 -0700 From: Nathan Bossart To: Michail Nikolaev Cc: PostgreSQL Hackers , Tom Lane Subject: Re: Replace known_assigned_xids_lck by memory barrier Message-ID: <20230816200715.GB2908487@nathanxps13> References: <20230814153634.GB1395427@nathanxps13> <20230815152224.GA2296544@nathanxps13> <20230816183236.GA2812457@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="8P1HSweYDcXXzwPJ" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --8P1HSweYDcXXzwPJ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Aug 16, 2023 at 09:29:10PM +0200, Michail Nikolaev wrote: > As answer: probably we need to change > "If we know that we're holding ProcArrayLock exclusively, we don't > need the read barrier." > to > "If we're removing xid, we don't need the read barrier because only > the startup process can remove and add xids to KnownAssignedXids" Ah, that explains it. v5 of the patch is attached. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --8P1HSweYDcXXzwPJ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v5-0001-Replace-known_assigned_xids_lck-with-memory-barri.patch" From 6038182ac96226f0eec43b1c6ab2e060e8b1e3a8 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 16 Aug 2023 10:52:56 -0700 Subject: [PATCH v5 1/1] Replace known_assigned_xids_lck with memory barriers. Suggested-by: Tom Lane Author: Michail Nikolaev Discussion: https://postgr.es/m/CANtu0oh0si%3DjG5z_fLeFtmYcETssQ08kLEa8b6TQqDm_cinroA%40mail.gmail.com --- src/backend/storage/ipc/procarray.c | 72 +++++++++++------------------ 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 2a3da49b8f..401e816275 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -61,7 +61,6 @@ #include "port/pg_lfind.h" #include "storage/proc.h" #include "storage/procarray.h" -#include "storage/spin.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/rel.h" @@ -82,7 +81,6 @@ typedef struct ProcArrayStruct int numKnownAssignedXids; /* current # of valid entries */ int tailKnownAssignedXids; /* index of oldest valid element */ int headKnownAssignedXids; /* index of newest element, + 1 */ - slock_t known_assigned_xids_lck; /* protects head/tail pointers */ /* * Highest subxid that has been removed from KnownAssignedXids array to @@ -441,7 +439,6 @@ CreateSharedProcArray(void) procArray->numKnownAssignedXids = 0; procArray->tailKnownAssignedXids = 0; procArray->headKnownAssignedXids = 0; - SpinLockInit(&procArray->known_assigned_xids_lck); procArray->lastOverflowedXid = InvalidTransactionId; procArray->replication_slot_xmin = InvalidTransactionId; procArray->replication_slot_catalog_xmin = InvalidTransactionId; @@ -4561,14 +4558,11 @@ KnownAssignedTransactionIdsIdleMaintenance(void) * during normal running). Compressing unused entries out of the array * likewise requires exclusive lock. To add XIDs to the array, we just insert * them into slots to the right of the head pointer and then advance the head - * pointer. This wouldn't require any lock at all, except that on machines - * with weak memory ordering we need to be careful that other processors - * see the array element changes before they see the head pointer change. - * We handle this by using a spinlock to protect reads and writes of the - * head/tail pointers. (We could dispense with the spinlock if we were to - * create suitable memory access barrier primitives and use those instead.) - * The spinlock must be taken to read or write the head/tail pointers unless - * the caller holds ProcArrayLock exclusively. + * pointer. This doesn't require any lock at all, but on machines with weak + * memory ordering, we need to be careful that other processors see the array + * element changes before they see the head pointer change. We handle this by + * using memory barriers when reading or writing the head/tail pointers (unless + * the caller holds ProcArrayLock exclusively). * * Algorithmic analysis: * @@ -4806,22 +4800,15 @@ KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, pArray->numKnownAssignedXids += nxids; /* - * Now update the head pointer. We use a spinlock to protect this - * pointer, not because the update is likely to be non-atomic, but to - * ensure that other processors see the above array updates before they - * see the head pointer change. - * - * If we're holding ProcArrayLock exclusively, there's no need to take the - * spinlock. + * Now update the head pointer. We use a write barrier to ensure that + * other processors see the above array updates before they see the head + * pointer change. The barrier isn't required if we're holding + * ProcArrayLock exclusively. */ - if (exclusive_lock) - pArray->headKnownAssignedXids = head; - else - { - SpinLockAcquire(&pArray->known_assigned_xids_lck); - pArray->headKnownAssignedXids = head; - SpinLockRelease(&pArray->known_assigned_xids_lck); - } + if (!exclusive_lock) + pg_write_barrier(); + + pArray->headKnownAssignedXids = head; } /* @@ -4843,20 +4830,15 @@ KnownAssignedXidsSearch(TransactionId xid, bool remove) int tail; int result_index = -1; - if (remove) - { - /* we hold ProcArrayLock exclusively, so no need for spinlock */ - tail = pArray->tailKnownAssignedXids; - head = pArray->headKnownAssignedXids; - } - else - { - /* take spinlock to ensure we see up-to-date array contents */ - SpinLockAcquire(&pArray->known_assigned_xids_lck); - tail = pArray->tailKnownAssignedXids; - head = pArray->headKnownAssignedXids; - SpinLockRelease(&pArray->known_assigned_xids_lck); - } + tail = pArray->tailKnownAssignedXids; + head = pArray->headKnownAssignedXids; + + /* + * Only the startup process removes entries, so we don't need the read + * barrier in that case. + */ + if (!remove) + pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */ /* * Standard binary search. Note we can ignore the KnownAssignedXidsValid @@ -5094,13 +5076,11 @@ KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, * cannot enter and then leave the array while we hold ProcArrayLock. We * might miss newly-added xids, but they should be >= xmax so irrelevant * anyway. - * - * Must take spinlock to ensure we see up-to-date array contents. */ - SpinLockAcquire(&procArray->known_assigned_xids_lck); tail = procArray->tailKnownAssignedXids; head = procArray->headKnownAssignedXids; - SpinLockRelease(&procArray->known_assigned_xids_lck); + + pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */ for (i = tail; i < head; i++) { @@ -5147,10 +5127,10 @@ KnownAssignedXidsGetOldestXmin(void) /* * Fetch head just once, since it may change while we loop. */ - SpinLockAcquire(&procArray->known_assigned_xids_lck); tail = procArray->tailKnownAssignedXids; head = procArray->headKnownAssignedXids; - SpinLockRelease(&procArray->known_assigned_xids_lck); + + pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */ for (i = tail; i < head; i++) { -- 2.25.1 --8P1HSweYDcXXzwPJ--