On Sun, Aug 18, 2024 at 10:01:42AM GMT, Paul E. McKenney wrote:
> But you only need one callback per live outstanding "cookie" returned
> from get_state_synchronize_rcu*() or start_poll_synchronize_rcu().
> Or am I missing something here?

Maybe I am?

I've been assuming that if rcu callbacks are getting punted off to a
kthread that we can't rely on them being completed in any particular
timeframe - i.e. the number of grace periods with outstanding callbacks
would be unbounded.

You're saying that NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE _does_ include
grace periods with outstanding callbacks? Just want to be clear on that.

> If so, create a structure that as an rcu_head structure and a
> cookies.  Create an array of this structure (possibly on a per-CPU,
> per-shard, or whatever basis), sized by NUM_ACTIVE_RCU_POLL_OLDSTATE or
> NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE, depending on which set of APIs you
> are using.  Have a lock that guards the full array.
> 
> You also need some sort of structure tracking whatever data elements
> for which the grace periods are intended, but I will not speculate
> on what that might be.
> 
> Then when you have a data element that needs to wait for a grace period:
> 
> 1.    Get a cookie from get_state_synchronize_rcu() or similar.
> 
> 2.    Acquire the lock.
> 
> 3.    If this cookie is already in the array, release the lock and
>       you are done.  (Give or take associating the cookie with the
>       data element, however you choose to do this.)
> 
> 4.    If this cookie has already expired (it can happen!), set the new
>       data element up to be processed (or maybe process it immediately,
>       as the case may be).  Proceed to the next step only for unexpired
>       new cookies, otherwise, release the lock.

There's another race, though - we're associating sequence numbers from
get_state_synchrize_rcu() with call_rcu() callbacks, and that's racy -
they can end up with different grace periods...

I think solving that would require a call_rcu_for_gp() API that takes
the sequence number we previously got from get_state_synchronize_rcu().

I think we can avoid your race in #4 entirely by simply waiting until we
have irqs disabled to call get_state_synchronize_rcu() (at least for the
normal RCU variant, the SRCU variant will naturally need a
srcu_read_lock() if we want to handle it that way).

That might be beneficial because then call_rcu_for_gp() can never race
with the grace period expiring.

Reply via email to