Messages in this thread | | | Date | Fri, 6 Sep 2019 09:07:36 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH 2/3] task: RCU protect tasks on the runqueue |
| |
On Thu, Sep 05, 2019 at 03:02:49PM -0500, Eric W. Biederman wrote: > Paul, what is the purpose of the barrier in rcu_assign_pointer? > > My intuition says it is the assignment half of rcu_dereference, and that > anything that rcu_dereference does not need is too strong.
I see that Paul has also replied, but let me give another take on it.
RCU does *two* different but related things. It provide object consistency and it provides object lifetime management.
Object consistency is provided by rcu_assign_pointer() / rcu_dereference:
- rcu_assign_pointer() is a PUBLISH operation, it is meant to expose an object to the world. In that respect it needs to ensure that all previous stores to this object are complete before it writes the pointer and exposes the object.
To this purpose, rcu_assign_pointer() is an smp_store_release().
- rcu_dereference() is a CONSUME operation. It matches the PUBLISH from above and guarantees that any further loads/stores to the observed object come after.
Naturally this would be an smp_load_acquire(), _HOWEVER_, since we need the address of the object in order to construct a load/store from/to said object, we can rely on the address-dependency to provide this barrier (except for Alpha, which is fscking weird). After all if you haven't completed the load of the (object) base address, you cannot compute the object member address and issue any subsequent memops, now can you ;-)
Now the thing here is that the 'rq->curr = next' assignment does _NOT_ expose the task (our object). The task is exposed the moment it enters the PID hash. It is this that sets us free of the PUBLISH requirement and thus we can use RCU_INIT_POINTER().
The object lifetime thing is provided by rcu_read_load()/rcu_read_unlock() on the one hand and synchronize_rcu()/call_rcu() on the other. That ensures that if you observe an object inside the RCU read side section, the object storage must stay valid.
And it is *that* properpy we wish to make use of.
Does this make sense to you?
| |