On 28/07/2015 15:29, Wen Congyang wrote: >>> >> >> If you call it just once, you have the same problem as before. In fact, >> it's worse because instead of having an overflow every 2^31 periods, you >> have one every 2 periods. Instead, by checking that rcu_reader went >> through 1 _and_ 3 (or that it was at least once 0, i.e. the thread was >> quiescent), you are sure that the thread went through _at least one_ >> grace period. > > The overflow is acceptable. We only compare if rcu_reader.ctr is equal than > rcu_gp_ctr. If not, we should wait that thread to call rcu_read_unlock(). > We don't care which is bigger. If no threads calls sync_rcu(), all threads > rcu_read.ctr is 0 or rcu_gp_ctr. If one thread calls sync_rcu(), all > threads rcu_read.ctr is 0, old_rcu_gp_ctr, or new_rcu_gp_ctr. We only wait the > thread that's rcu_read.ctr is old_rcu_gp_ctr.
Suppose you have reader writer --------------------------------------------------------------- rcu_read_lock() ctr = atomic_read(&rcu_gp_ctr); ctr = 1 synchronize_rcu() rcu_gp_ctr = 3 atomic_xchg(&p_rcu_reader->ctr, ctr); rcu_reader.ctr = 1 We're in the critical section. synchronize_rcu() rcu_gp_ctr = 1 rcu_gp_ongoing(&p_rcu_reader->ctr) returns false, so synchronize_rcu() exits. But we're still in the critical section. p = atomic_rcu_read(&foo); g_free(p); Boom. :) For more information see http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.220.8810 Paolo