Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jgXzR-00049w-Ob for pgsql-hackers@arkaria.postgresql.org; Wed, 03 Jun 2020 18:19:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jgXzQ-0005mt-8F for pgsql-hackers@arkaria.postgresql.org; Wed, 03 Jun 2020 18:19:48 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jgXzQ-0005mm-1z for pgsql-hackers@lists.postgresql.org; Wed, 03 Jun 2020 18:19:48 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jgXzN-0006Y9-VV for pgsql-hackers@lists.postgresql.org; Wed, 03 Jun 2020 18:19:47 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 053IJjJ71141820 for ; Wed, 3 Jun 2020 14:19:45 -0400 From: Tom Lane To: pgsql-hackers@lists.postgresql.org Subject: Atomic operations within spinlocks MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1141818.1591208385.1@sss.pgh.pa.us> Date: Wed, 03 Jun 2020 14:19:45 -0400 Message-ID: <1141819.1591208385@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk In connection with the nearby thread about spinlock coding rule violations, I noticed that we have several places that are doing things like this: SpinLockAcquire(&WalRcv->mutex); ... written_lsn = pg_atomic_read_u64(&WalRcv->writtenUpto); ... SpinLockRelease(&WalRcv->mutex); That's from pg_stat_get_wal_receiver(); there is similar code in freelist.c's ClockSweepTick() and StrategySyncStart(). This seems to me to be very bad code. In the first place, on machines without the appropriate type of atomic operation, atomics.c is going to be using a spinlock to emulate atomicity, which means this code tries to take a spinlock while holding another one. That's not okay, either from the standpoint of performance or error-safety. In the second place, this coding seems to me to indicate serious confusion about which lock is protecting what. In the above example, if writtenUpto is only accessed through atomic operations then it seems like we could just move the pg_atomic_read_u64 out of the spinlock section; or if the spinlock is adequate protection then we could just do a normal fetch. If we actually need both locks then this needs significant re-thinking, IMO. Comments? regards, tom lane