maybe dumb question about RCU
Jeff Haran
Jeff.Haran at citrix.com
Mon Apr 13 17:13:16 EDT 2015
> -----Original Message-----
> From: Andev [mailto:debiandev at gmail.com]
> Sent: Monday, April 13, 2015 2:01 PM
> To: Jeff Haran
> Cc: kernelnewbies
> Subject: Re: maybe dumb question about RCU
>
> On Fri, Apr 10, 2015 at 4:34 PM, Jeff Haran <Jeff.Haran at citrix.com> wrote:
> >> > The msleep() happens after the
> >> > rcu_assign_pointer()/synchronize_rcu()
> >> sequence, not in the middle of it. All that msleep() is for is to
> >> make sure the updater isn't spinning that core and I chose the value
> >> so that the updater which thus runs every 1.5 seconds doesn't beat
> >> with the reader that is holding the rcu read lock for 1 second. Now
> >> one can argue that this in the reader is an atypically long time to hold a
> RCU read lock:
> >> >
> >> > rcu_read_lock();
> >> > a = rcu_dereference(rcu_pointer);
> >> > start = get_jiffies_64();
> >> > while (get_jiffies_64() < (start + 1000));
> >> > b = rcu_dereference(rcu_pointer);
> >> > rcu_read_unlock();
> >> >
> >> > That causes the RCU read "lock" to be held for 1 second (at least
> >> > on
> >> systems where a jiffie is a millisecond). But if that's "too long"
> >> then how long exactly is "too long"? If 1 second is too long, is 1
> >> millisecond too long? How is the developer using this interface to
> >> know either how long is too long or how long the code they've written
> >> will take to execute given the plethora of different systems it might run
> on?
>
>
> So I looked closely at your code and found the cause for your seeing
> different values for the pointer.
>
> What is happening is as follows:
>
>
> reader updater
> --------------------------------------------------------------------------
> rcu_assign_pointer(rcu_pointer, p1);
> synchronize_rcu(); // returns immediately
> // no rcu read CS active
> rcu_read_lock();
> a = rcu_pointer;//p1 // loop again
> rcu_assign_pointer(rcu_pointer, p2);
> // this is immediately visible to reader
> b = rcu_pointer; //p2
> rcu_read_unlock();
> synchronize_rcu(); // returns immediately
> // no rcu read CS active
>
> This is just one possible run which will cause you to see different values of
> rcu_pointer. There are possibly more.
>
> Now what can you do to prevent such updates happening to pointers?
>
> The obvious solution is to use mutex between readers and updaters. But we
> want to use RCU.
>
> Dereference the pointer only once within the read critical section. If you are
> dereferencing twice, be ready to handle the case where the pointer has
> been changed.
>
> The guarantee that RCU provides is that p1 will not be freed until the read
> critical section which holds a reference to p1 has completed.
>
> --
> Andev
Sounds like we have come to the same conclusion then.
Thanks,
Jeff Haran
More information about the Kernelnewbies
mailing list