NetBSD Problem Report #56832
From www@netbsd.org Sat May 14 00:58:29 2022
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 5241F1A9239
for <gnats-bugs@gnats.NetBSD.org>; Sat, 14 May 2022 00:58:29 +0000 (UTC)
Message-Id: <20220514005827.C03A11A923C@mollari.NetBSD.org>
Date: Sat, 14 May 2022 00:58:27 +0000 (UTC)
From: tgl@sss.pgh.pa.us
Reply-To: tgl@sss.pgh.pa.us
To: gnats-bugs@NetBSD.org
Subject: __atomic_compare_exchange[_n] is wrong on non-mainstream platforms
X-Send-Pr-Version: www-1.0
>Number: 56832
>Category: lib
>Synopsis: __atomic_compare_exchange[_n] is wrong on non-mainstream platforms
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat May 14 01:00:01 +0000 2022
>Closed-Date: Sun May 15 17:12:23 +0000 2022
>Last-Modified: Mon May 16 06:20:01 +0000 2022
>Originator: Tom Lane
>Release: HEAD/202205021430Z (problem is old, though)
>Organization:
PostgreSQL Global Development Group
>Environment:
NetBSD sss2.sss.pgh.pa.us 9.99.96 NetBSD 9.99.96 (GENERIC) #0: Wed May 11 15:39:57 EDT 2022 tgl@nuc1.sss.pgh.pa.us:/home/tgl/netbsd-H-202205021430Z/obj.hppa/sys/arch/hppa/compile/GENERIC hppa
>Description:
The C11 spec defines __atomic_compare_exchange[_n] as:
bool __atomic_compare_exchange_n (type *ptr, type *expected, type desired, bool weak, int success_memorder, int failure_memorder)
This built-in function implements an atomic compare and exchange operation. This compares the contents of *ptr with the contents of *expected. If equal, the operation is a read-modify-write operation that writes desired into *ptr. If they are not equal, the operation is a read and
the current contents of *ptr are written into *expected. [etc]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(Actually, I'm quoting the GCC docs because I don't have C11 at hand. But it's hard to see why the "expected" argument would be defined as a pointer if there were no intention of updating its value.)
The implementations of these functions in common/lib/libc/atomic/atomic_c11_compare_exchange_cas_*.c fail to perform the step of storing the contents of *ptr back into *expected.
This appears to have been wrong since these functions were added in 2014. I surmise that it hasn't been noticed because (a) these implementations are only used on non-mainstream platforms, and/or (b) most programs don't rely on the detail of *expected getting updated.
>How-To-Repeat:
Inspection of the source code is sufficient to show that these functions never update *expected.
Alternatively, running PostgreSQL's "make check" tests on an affected platform (I was using HPPA) will usually show the problem, in the form of some process getting stuck in a wait loop.
>Fix:
It could be coded in a couple of ways, but I did this:
Index: common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c,v
retrieving revision 1.3
diff -u -r1.3 atomic_c11_compare_exchange_cas_32.c
--- common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c 7 Sep 2020 00:52:19 -0000 1.3
+++ common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c 14 May 2022 00:19:46 -0000
@@ -45,11 +45,16 @@
bool weak, int success, int failure)
{
uint32_t old = *(uint32_t *)expected;
+ uint32_t prev;
/*
* Ignore the details (weak, memory model on success and failure)
* and just do the cas. If we get here the compiler couldn't
* do better and it mostly will not matter at all.
*/
- return atomic_cas_32(mem, old, desired) == old;
+ prev = atomic_cas_32(mem, old, desired);
+ if (prev == old)
+ return true;
+ *(uint32_t *)expected = prev;
+ return false;
}
and similarly in the other two files.
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->pending-pullups
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Sat, 14 May 2022 05:40:54 +0000
State-Changed-Why:
Fix committed. Pending pullups now.
From: Nick Hudson <nick.hudson@gmx.co.uk>
To: gnats-bugs@netbsd.org, lib-bug-people@netbsd.org, netbsd-bugs@netbsd.org,
gnats-admin@netbsd.org, tgl@sss.pgh.pa.us
Cc:
Subject: Re: lib/56832 (__atomic_compare_exchange[_n] is wrong on
non-mainstream platforms)
Date: Sun, 15 May 2022 09:08:11 +0100
[pullup-9 #1451] lib/56832 fix
From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/56832 CVS commit: [netbsd-9] src/common/lib/libc/atomic
Date: Sun, 15 May 2022 12:37:00 +0000
Module Name: src
Committed By: martin
Date: Sun May 15 12:37:00 UTC 2022
Modified Files:
src/common/lib/libc/atomic [netbsd-9]:
atomic_c11_compare_exchange_cas_16.c
atomic_c11_compare_exchange_cas_32.c
atomic_c11_compare_exchange_cas_8.c
Log Message:
Pull up following revision(s) (requested by skrll in ticket #1451):
common/lib/libc/atomic/atomic_c11_compare_exchange_cas_8.c: revision 1.4
common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c: revision 1.4
common/lib/libc/atomic/atomic_c11_compare_exchange_cas_16.c: revision 1.4
PR 56832:
fix C implementations of __atomic_compare_exchange*
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.2.20.1 \
src/common/lib/libc/atomic/atomic_c11_compare_exchange_cas_16.c \
src/common/lib/libc/atomic/atomic_c11_compare_exchange_cas_32.c \
src/common/lib/libc/atomic/atomic_c11_compare_exchange_cas_8.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: pending-pullups->closed
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Sun, 15 May 2022 17:12:23 +0000
State-Changed-Why:
pullup processed.
Thanks for the PR.
From: Tom Lane <tgl@sss.pgh.pa.us>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: lib/56832: __atomic_compare_exchange[_n] is wrong on non-mainstream platforms
Date: Sun, 15 May 2022 14:02:00 -0400
Hmm, the version of this that was pulled up into netbsd-9 has one
serious error: atomic_c11_compare_exchange_cas_32.c uses atomic_cas_8
where it should use atomic_cas_32. I did not look at HEAD but
I suppose it's got the same problem.
regards, tom lane
From: Nick Hudson <nick.hudson@gmx.co.uk>
To: gnats-bugs@netbsd.org, lib-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, tgl@sss.pgh.pa.us
Cc:
Subject: Re: lib/56832: __atomic_compare_exchange[_n] is wrong on
non-mainstream platforms
Date: Mon, 16 May 2022 07:15:33 +0100
> Hmm, the version of this that was pulled up into netbsd-9 has one
> serious error: atomic_c11_compare_exchange_cas_32.c uses atomic_cas_8
> where it should use atomic_cas_32. I did not look at HEAD but
> I suppose it's got the same problem.
Good spot.
[pullup-9 #1453] more lib/56832: Fwd: CVS commit: src/common/lib/libc/atomic
Thanks,
Nick
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.