On Fri, Apr 10, 2015 at 12:47 PM, Jeff Haran <[email protected]> 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?
>
> The documentation I've seen says that the only restriction on RCU readers is 
> that they don't block and the above doesn't so it satisfies the requirements 
> of the interface near as I can tell.

This section of the code might still be pre-empted. Try putting a
preempt_disable() at the beginning and see if you are getting the same
value or not.

Relevant comment here:
http://lxr.free-electrons.com/source/include/linux/rcupdate.h#L837

>
> The conclusion I've come to is that the read critical section is *NOT* there 
> to make sure that the value returned by rcu_dereference() of a given pointer 
> doesn't change within the RCU read critical section (the code delimited by 
> the rcu_read_lock() and rcu_read_unlock()).
>
> Rather the purpose of rcu_read_lock()/rcu_read_unlock() is there to keep 
> synchronize_rcu() at bay so that the updater can safely free any memory block 
> that may have been overwritten in the most recent call to 
> rcu_assign_pointer(). The example I provided where rcu_pointer just 
> oscillates between two different addresses of static buffers was done that 
> way to make it simple. More typically, the pointers passed as the second 
> parameter to rcu_assign_pointer() point to allocated memory. When updaters do 
> that, they need to free those pointers eventually but they can't do that 
> until they know that all readers aren't accessing them anymore. Normally, any 
> freeing would happen after synchronize_rcu() returned and the read critical 
> section is there to tell synchronize_rcu() when its safe to return and let 
> the updater free the old memory block.
>
> At least that's how I read it now.
>
> Jeff Haran
>



-- 
Andev

_______________________________________________
Kernelnewbies mailing list
[email protected]
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Reply via email to