mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Frederic Weisbecker <frederic@kernel.org>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Thomas Gleixner <tglx@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	boqun@kernel.org, LKML <linux-kernel@vger.kernel.org>,
	"Cc: Hyunwoo Kim" <imv4bel@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>,
	Christian Brauner <brauner@kernel.org>,
	John Stultz <jstultz@google.com>, Ingo Molnar <mingo@kernel.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	stable@vger.kernel.org
Subject: Re: [patch V2 1/8] signal: Prevent exec() race
Date: Fri, 11 Sep 2026 14:27:56 +0200	[thread overview]
Message-ID: <aqPzzMlPpXMNZ5WC@localhost.localdomain> (raw)
In-Reply-To: <541b1db8-8649-46a9-9fa1-1b5f93cded7f@rowland.harvard.edu>

Le Thu, Sep 10, 2026 at 11:26:38AM -0400, Alan Stern a écrit :
> On Thu, Sep 10, 2026 at 03:21:54PM +0200, Frederic Weisbecker wrote:
> > Alan, let me ask you something, because I'm the only one here puzzled by
> > this data dependency.
> > 
> > The following scenario works (the bad outcome never happens) because
> > UNLOCK+LOCK pairs with smp_load_acquire():
> > 
> > 	C MP+polocks
> > 
> > 	{}
> > 
> > 	P0(int *A, int *B, spinlock_t *mylock)
> > 	{
> > 		spin_lock(mylock);
> > 		WRITE_ONCE(*A, 1);
> > 		spin_unlock(mylock);
> > 		spin_lock(mylock);
> > 		WRITE_ONCE(*B, 1);
> > 		spin_unlock(mylock);
> > 	}
> > 
> > 	P1(int *A, int *B)
> > 	{
> > 		int r0;
> > 		int r1;
> > 
> > 		r0 = smp_load_acquire(B);
> > 		r1 = READ_ONCE(*A);
> > 	}
> > 
> > 	exists (1:r0=1 /\ 1:r1=0) (* Bad outcome. *)
> > 
> > 
> > So I understand this one. Now unfortunately litmus doesn't support
> > structures, but let's suppose it could. I'm taking the previous script
> > and introduce a small change in P1:
> > 
> > 	C MP+polocks
> > 
> > 	{}
> > 
> > 	P0(int *A, int *B, spinlock_t *mylock)
> > 	{
> > 		spin_lock(mylock);
> > 		WRITE_ONCE(*A, 1);
> > 		spin_unlock(mylock);
> > 		spin_lock(mylock);
> > 		WRITE_ONCE(*B, 1);
> > 		spin_unlock(mylock);
> > 	}
> > 
> > 	P1(int *A, int *B)
> > 	{
> > 		int r0;
> > 		int r1
> > 
> > 		r0 = READ_ONCE(*B);
> > 		spin_lock(r0->somelock)
> > 		r1 = READ_ONCE(*A);
> > 		spin_unlock(r0->somelock)
> > 	}
> > 
> > 	exists (1:r0=1 /\ 1:r1=0) (* Bad outcome. *)
> > 
> > 
> > So instead of doing a LOAD-ACQUIRE on B, I do a plain READ but I also
> > do a spin_lock right after on a data that depends on that READ. I can't
> > run that on litmus but this is the same (simplified) pattern as what we
> > had in this discussion and therefore I assume that it also works (ie: the
> > bad outcome shouldn't happen), is that right?
> 
> Yes.
> 
> > Would it also work if spin_lock() was just a LOAD-ACQUIRE?
> 
> Yes.
> 
> > Does it mean that data dependency implies sufficient ordering such that
> > a LOAD-ACQUIRE to a data that depends on B provides the same guarantees as
> > a LOAD-ACQUIRE to B?
> 
> Indeed it does, with the obvious exception that a load-acquire of B 
> also provides ordering to any statements in between it and the load of 
> the data depending on B.  That is:
> 
> 	r0 = smp_load_acquire(B);
> 	X;
> 	r1 = READ_ONCE(r0->A);
> 
> orders the load from B before everything that follows, including X, 
> whereas:
> 
> 	r0 = READ_ONCE(B);
> 	X;
> 	r1 = smp_load_acquire(r0->A);
> 
> orders the load from B before the load from r0->A and everything 
> following it, but not before X.

Ok that matches my understanding.

> 
> > The reason I'm asking that is because, unlike control dependency, data
> > dependency and its guarantees are not well documented. It is defined in
> > tools/memory-model/Documentation/explanation.txt but not really described
> > in Documentation/memory-barriers.txt. There is a mention in a scenario within
> > the section "MULTICOPY ATOMICITY" just to show that it's not as strong as
> > a full memory barrier.
> > 
> > So if data dependency can provide the guarantee above in my second script
> > but it's not as strong as a full barrier, this suggests that data dependencies
> > have their own specific properties that should probably be documentated.
> 
> Perhaps so.  Can you suggest a place in explanations.txt that could be 
> improved?

So in explanations.txt, the different kinds of dependencies are defined
without diving much into properties.

Properties of ordering enforcement tools are typically described in
Documentation/memory-barriers.txt. Control dependencies has its own
section and I suspect there is enough to say about data dependencies
to deserve its own section there.

What I would love to see documented for example is our case: acquire semantics,
which are described to apply one-way from a single memory target, are also
transferrable to other memory targets when there is a data dependency
involved between them.

> Here's how I think about ordering guarantees in general.  Not in terms 
> of pairing of memory barriers, since (as you pointed out) dependencies 
> aren't memory barriers, and also since ordering cycles can involve more 
> than two CPUs (so triples or higher, not just pairs).
> 
> Instead there's a hierarchy of ordering classes.  The lowest level only 
> orders events on a single CPU; it includes dependencies, smp_rmb(), and 
> load-acquires.
> 
> The next level orders cross-CPU events (i.e., writes), but only in a way 
> that affects two CPUs at a time.  It includes things like smp_wmb() and 
> store-releases, and it guarantees that if CPU 1 writes A first and B 
> second, then CPU 2 will observe the store to A before it observes the 
> store to B.  Likewise for CPU 3, CPU 4, etc., but there is no guarantee 
> about the order in which differing CPUs will observe the stores.
> 
> The highest level orders events in a way that involves all CPUs.  It 
> includes things like smp_mb() and synchronize_rcu(), and it says that if 
> CPU 1 writes A first and B second, then _every_ CPU will observe the 
> store to A before _any_ CPU (including CPU 1!) observes the store to B.
> 
> This is a little imprecise, and there are varying details within the 
> levels, but the overall idea is basically right.

Interesting way of seeing it and I *think* I understand :-)

> 
> At any rate, the point you're raising is that dependencies and 
> load-acquires both sit at the lowest level of this hierarchy, so they 
> provide pretty much the same ordering guarantees.
> 
> Alan Stern

Got it.

Thanks a lot for taking the time to explain me all that!

-- 
Frederic Weisbecker
SUSE Labs

  reply	other threads:[~2026-09-11 12:27 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-05 18:58 [patch V2 0/8] exec/exit: POSIX timer related bugfixes and related cleanups Thomas Gleixner
2026-09-05 18:59 ` [patch V2 1/8] signal: Prevent exec() race Thomas Gleixner
2026-09-06 13:17   ` Oleg Nesterov
2026-09-06 22:39   ` Eric W. Biederman
2026-09-06 23:28     ` Oleg Nesterov
2026-09-07 11:26     ` Thomas Gleixner
2026-09-07 12:31   ` Frederic Weisbecker
2026-09-07 15:26     ` Thomas Gleixner
2026-09-07 20:15       ` Frederic Weisbecker
2026-09-07 22:28         ` Thomas Gleixner
2026-09-08 10:15           ` Frederic Weisbecker
2026-09-09  0:03             ` Oleg Nesterov
2026-09-09  9:17               ` Frederic Weisbecker
2026-09-09  8:04             ` Peter Zijlstra
2026-09-09  9:08               ` Thomas Gleixner
2026-09-09  9:55                 ` Peter Zijlstra
2026-09-09 10:20                   ` Peter Zijlstra
2026-09-09 11:31                   ` Thomas Gleixner
2026-09-09 12:13                   ` Frederic Weisbecker
2026-09-09 12:45                     ` Peter Zijlstra
2026-09-09 12:51                       ` Peter Zijlstra
2026-09-09 13:45                         ` Thomas Gleixner
2026-09-09 15:48                           ` Frederic Weisbecker
2026-09-09 16:00                           ` Frederic Weisbecker
2026-09-09 14:33                       ` Alan Stern
2026-09-09 14:45                       ` Frederic Weisbecker
2026-09-09 19:28                         ` Alan Stern
2026-09-09 20:49                           ` Thomas Gleixner
2026-09-09 21:11                             ` Alan Stern
2026-09-10 13:21                               ` Frederic Weisbecker
2026-09-10 13:28                                 ` Peter Zijlstra
2026-09-11  9:58                                   ` Frederic Weisbecker
2026-09-11 10:22                                     ` Peter Zijlstra
2026-09-11 12:36                                       ` Frederic Weisbecker
2026-09-11 14:52                                       ` Alan Stern
2026-09-10 15:26                                 ` Alan Stern
2026-09-11 12:27                                   ` Frederic Weisbecker [this message]
2026-09-09 10:18                 ` Frederic Weisbecker
2026-09-09  9:11               ` Frederic Weisbecker
2026-09-05 18:59 ` [patch V2 2/8] exec: Cleanup POSIX timers right after de_thread() Thomas Gleixner
2026-09-06 13:21   ` Oleg Nesterov
2026-09-07 22:13   ` Frederic Weisbecker
2026-09-05 18:59 ` [patch V2 3/8] posix-timers: Move posixtimer_exec_cleanup() out of exec.c Thomas Gleixner
2026-09-10 13:50   ` Frederic Weisbecker
2026-09-05 18:59 ` [patch V2 4/8] posix-timers: Move POSIX timer group exit related code out of do_exit() Thomas Gleixner
2026-09-10 13:59   ` Frederic Weisbecker
2026-09-05 18:59 ` [patch V2 5/8] posix-cpu-timers: Move inlines out of public header Thomas Gleixner
2026-09-10 14:00   ` Frederic Weisbecker
2026-09-05 18:59 ` [patch V2 6/8] posix-cpu-timers: Use PF_EXITING to indicate exit Thomas Gleixner
2026-09-05 18:59 ` [patch V2 7/8] posix-cpu-timers: Prevent enqueueing when PF_EXITING is set Thomas Gleixner
2026-09-06 16:26   ` Oleg Nesterov
2026-09-07 12:20     ` Thomas Gleixner
2026-09-05 18:59 ` [patch V2 8/8] posix-timers: Handle exit in do_exit() completely Thomas Gleixner
2026-09-06 16:40   ` Oleg Nesterov
2026-09-07 12:27     ` Thomas Gleixner

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=aqPzzMlPpXMNZ5WC@localhost.localdomain \
    --to=frederic@kernel.org \
    --cc=boqun@kernel.org \
    --cc=brauner@kernel.org \
    --cc=ebiederm@xmission.com \
    --cc=imv4bel@gmail.com \
    --cc=jstultz@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=tglx@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /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

all inboxes | Powered by JetHome®