> This is a permanent error; I've given up. Sorry it didn't
work out.
hopefully with just one main thought per email! :-)
Yes, I meant for the srcu : ) Any argument I'm trying to make just for rcu right now, will need to still work for srcu later.
On Wed, Jan 18, 2023 at 12:25:05PM +0100, Jonas Oberhauser wrote:
No, you're mixing up RCU and SRCU.
On 1/17/2023 10:19 PM, Alan Stern wrote:
On Tue, Jan 17, 2023 at 06:48:12PM +0100, Jonas Oberhauser wrote:rscs are reads& writes in herd. That's how the data dependency works in your
Pretending for simplicity that rscs and grace periods aren't reads&writesThey aren't. You don't have to pretend.
patch, right?
The issue I have with this is that it might create accidental ordering. How does it behave when you throw fences in the mix?I consider that a hack though and don't like it.It _is_ a bit of a hack, but not a huge one. srcu_read_lock() really
is a lot like a load, in that it returns a value obtained by reading
something from memory (along with some other operations, though, so it
isn't a simple straightforward read -- perhaps more like an
atomic_inc_return_relaxed).
srcu_read_unlock() is somewhat less like a store, but it does have oneOr if you could declare your own : )
notable similarity: It takes an input value and therefore can be the
target of a data dependency. The biggest difference is that an
srcu_read_unlock() can't really be read-from. It would be nice if herd
had an event type that behaved this way.
Also, herd doesn't have any way of saying that the value passed to a
store is an unmodified copy of the value obtained by a load. In our
case that doesn't matter much -- nobody should be writing litmus tests
in which the value returned by srcu_read_lock() is incremented and then
decremented again before being passed to srcu_write_lock()!
By golly, you're right! I'm still thinking in terms of an older
version of the memory model, which used gp in place of rcu-gp.
Note that if your ordering relies on actually using gp twice in a row, thenI don't know what you mean by this. The example above does rely on
these must come from strong-fence, but you should be able to just take the
shortcut by merging them into a single gp.
po;rcu-gp;po;rcu-gp;po <= gp <= strong-fence <= hb & strong-order
having two synchronize_rcu() calls; with only one it would be allowed.
Okay. So we could define rcu-order by:Because the the RCU Grace Period Guarantee doesn't say "if a gp happensI don't think rcu-order is necessary at all to define LKMM, and one canSure, you could do that, but it wouldn't make sense. Why would anyone
probably just use rcu-extend instead of rcu-order (and in fact even a
version of rcu-extend without any lone rcu-gps).
want to define an RCU ordering relation that includes
gp ... rscs ... gp ... rscs
but not
gp ... rscs ... rscs ... gp
?
before a gp, with some rscs in between, ...".
So I think even the picture is not the best picture to draw for RCU
ordering. I think the right picture to draw for RCU ordering is something
like this:
case (1): C ends before G does:
rcsc ... ... ... ... ... gp
case (2): G ends before C does:
gp ... ... ... ... ... rscs
where the dots are some relation that means "happens before".
let rec rcu-order = (rcu-gp ; rcu-link ; (rcu-order ; rcu-link)* ; rcu-rscsi) |
(rcu-rscsi ; rcu-link ; (rcu-order ; rcu-link)* ; rcu-gp)
(ignoring the SRCU cases). That is a little awkward; it might make
sense to factor out (rcu-link ; (rcu-order ; rcu-link)*) as a separate
relation and do a simultaneous recursion on both relations.
But either way, rcu-fence would have to be defined as (po ; rcu-order+ ; po?),
which looks a little odd.