From: Hernan Luis Ponce de Leon <hernanl.leon@huawei.com>
To: Jonas Oberhauser <jonas.oberhauser@huawei.com>,
Joel Fernandes <joel@joelfernandes.org>
Cc: Alan Stern <stern@rowland.harvard.edu>,
Boqun Feng <boqun.feng@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
"Paul E. McKenney" <paulmck@kernel.org>,
"parri.andrea@gmail.com" <parri.andrea@gmail.com>,
"will@kernel.org" <will@kernel.org>,
"npiggin@gmail.com" <npiggin@gmail.com>,
"dhowells@redhat.com" <dhowells@redhat.com>,
"j.alglave@ucl.ac.uk" <j.alglave@ucl.ac.uk>,
"luc.maranget@inria.fr" <luc.maranget@inria.fr>,
"akiyks@gmail.com" <akiyks@gmail.com>,
"dlustig@nvidia.com" <dlustig@nvidia.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-arch@vger.kernel.org" <linux-arch@vger.kernel.org>
Subject: RE: "Verifying and Optimizing Compact NUMA-Aware Locks on Weak Memory Models"
Date: Mon, 12 Sep 2022 11:10:17 +0000 [thread overview]
Message-ID: <7ad2354bf993435b917f278d4199a6ff@huawei.com> (raw)
In-Reply-To: <34735a476c3b4913985de3403a6216bd@huawei.com>
> Therefore this hang should be observable on a hypothetical LKMM processor
> which makes use of all the relaxed liberty the LKMM allows. However according
> to the authors of that paper (who are my colleagues but I haven't been involved
> deeply in that work), not even Power+gcc allow this reordering to happen, and if
> that's true it is probably because the wmb is mapped to lwsync which is fully
> cumulative in Power but not in LKMM.
All the "issues" we mention in the technical report are according to LKMM.
As shown by (*) below, as soon as the code gets compiled and verified against the
corresponding hardware memory model, the code is correct.
Here is a small variant of the litmus test I sent earlier where not only the "problematic
behavior" is allowed by LKMM, but where liveness is actually violated.
The code is written in C (main function and headers missing) and cannot be used directly
with herd7 (since I am not sure if the end of thread_3 can be written using herd7 syntax).
------------------------------------------------------------------------
int y, z;
atomic_t x;
void *thread_1(void *unused)
{
// clear_pending_set_locked
int r0 = atomic_fetch_add(2,&x) ;
}
void *thread_2(void *unused)
{
// this store breaks liveness
WRITE_ONCE(y, 1);
// queued_spin_trylock
int r0 = atomic_read(&x);
// barrier after the initialisation of nodes
smp_wmb();
// xchg_tail
int r1 = atomic_cmpxchg_relaxed(&x,r0,42);
// link node into the waitqueue
WRITE_ONCE(z, 1);
}
void *thread_3(void *unused)
{
// node initialisation
WRITE_ONCE(z, 2);
// queued_spin_trylock
int r0 = atomic_read(&x);
// barrier after the initialisation of nodes
smp_wmb();
// if we read z==2 we expect to read this store
WRITE_ONCE(y, 0);
// xchg_tail
int r1 = atomic_cmpxchg_relaxed(&x,r0,24);
// spinloop
while(READ_ONCE(y) == 1 && (READ_ONCE(z) == 2)) {}
}
------------------------------------------------------------------------
Liveness is violated (following Theorem 5.3 of the "Making weak memory models fair" paper) because the reads from the spinloop
can get their values from writes which come last in the coherence / modification order, and those values do not stop the spinning.
------------------------------------------------------------------------
$ java -jar $DAT3M_HOME/dartagnan/target/dartagnan-3.1.0.jar cat/linux-kernel.cat --target=lkmm --property=liveness liveness.c
...
Liveness violation found
FAIL
------------------------------------------------------------------------
(*) However, if the code is compiled (this transformation is done automatically and internally by the tool, notice the --target option)
and we use some hardware memory model, the tool says the code is correct
------------------------------------------------------------------------
$ java -jar $DAT3M_HOME/dartagnan/target/dartagnan-3.1.0.jar cat/aarch64.cat --target=arm8 --property=liveness liveness.c
...
PASS
$ java -jar $DAT3M_HOME/dartagnan/target/dartagnan-3.1.0.jar cat/power.cat --target=power --property=liveness liveness.c
...
PASS
$ java -jar $DAT3M_HOME/dartagnan/target/dartagnan-3.1.0.jar cat/riscv.cat --target=riscv --property=liveness liveness.c
...
PASS
------------------------------------------------------------------------
I think it is somehow possible to show the liveness violation using herd7 and the following variant of the code
------------------------------------------------------------------------
C Liveness
{
atomic_t x = ATOMIC_INIT(0);
atomic_t y = ATOMIC_INIT(0);
}
P0(atomic_t *x) {
// clear_pending_set_locked
int r0 = atomic_fetch_add(2,x) ;
}
P1(atomic_t *x, int *z, int *y) {
// this store breaks liveness
WRITE_ONCE(*y, 1);
// queued_spin_trylock
int r0 = atomic_read(x);
// barrier after the initialisation of nodes
smp_wmb();
// xchg_tail
int r1 = atomic_cmpxchg_relaxed(x,r0,42);
// link node into the waitqueue
WRITE_ONCE(*z, 1);
}
P2(atomic_t *x,int *z, int *y) {
// node initialisation
WRITE_ONCE(*z, 2);
// queued_spin_trylock
int r0 = atomic_read(x);
// barrier after the initialisation of nodes
smp_wmb();
// if we read z==2 we expect to read this store
WRITE_ONCE(*y, 0);
// xchg_tail
int r1 = atomic_cmpxchg_relaxed(x,r0,24);
// spinloop
int r2 = READ_ONCE(*y);
int r3 = READ_ONCE(*z);
}
exists (z=2 /\ y=1 /\ 2:r2=1 /\ 2:r3=2)
------------------------------------------------------------------------
Condition "2:r3=2" forces the spinloop to read from the first write in P2 and "z=2" forces this write
to be last in the coherence order. Conditions "2:r2=1" and "y=1" force the same for the other read.
herd7 says this behavior is allowed by LKMM, showing that liveness can be violated.
In all the examples above, if we use mb() instead of wmb(), LKMM does not accept
the behavior and thus liveness is guaranteed.
Hernan
next prev parent reply other threads:[~2022-09-12 11:10 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-26 12:48 "Verifying and Optimizing Compact NUMA-Aware Locks on Weak Memory Models" Paul E. McKenney
2022-08-26 16:21 ` Boqun Feng
2022-08-26 16:23 ` Peter Zijlstra
2022-08-26 17:10 ` Alan Stern
2022-08-26 20:42 ` Paul E. McKenney
2022-08-27 16:00 ` Alan Stern
2022-08-27 17:04 ` Paul E. McKenney
2022-09-13 11:24 ` Will Deacon
2022-09-13 12:21 ` Dan Lustig
2022-09-16 8:18 ` Will Deacon
2022-08-26 23:47 ` Peter Zijlstra
2022-08-27 16:05 ` Alan Stern
2022-08-27 16:44 ` Boqun Feng
2022-08-29 2:15 ` Andrea Parri
2022-09-09 11:45 ` Jonas Oberhauser
2022-09-10 12:11 ` Hernan Luis Ponce de Leon
2022-09-10 15:03 ` Alan Stern
2022-09-10 20:41 ` Hernan Luis Ponce de Leon
2022-09-11 10:20 ` Joel Fernandes
2022-09-12 10:13 ` Jonas Oberhauser
2022-09-12 11:10 ` Hernan Luis Ponce de Leon [this message]
2022-09-14 14:41 ` Alan Stern
2022-09-12 12:01 ` Alan Stern
2022-09-11 14:53 ` Andrea Parri
2022-09-12 10:46 ` Jonas Oberhauser
2022-09-12 12:02 ` Alan Stern
2022-08-29 2:33 ` Andrea Parri
2022-08-29 12:25 ` Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7ad2354bf993435b917f278d4199a6ff@huawei.com \
--to=hernanl.leon@huawei.com \
--cc=akiyks@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=dhowells@redhat.com \
--cc=dlustig@nvidia.com \
--cc=j.alglave@ucl.ac.uk \
--cc=joel@joelfernandes.org \
--cc=jonas.oberhauser@huawei.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luc.maranget@inria.fr \
--cc=npiggin@gmail.com \
--cc=parri.andrea@gmail.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=stern@rowland.harvard.edu \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).