Rcu synchronization of a list

From: Nikolay Borisov
Date: Fri May 27 2016 - 05:41:01 EST


I'm currently dealing with a synchronization scheme which utilizes RCU
but I'm observing a race condition. So I have an rcu-enabled list, which
contains various entries. The add/delete paths of the list are protected
by a single spin_lock. I'm observing the following thing happening:

T1 T2
1. init_count
2. delete_group

So 'init_count' checks the list for a particular entry under
rcu_read_lock and will either return the existing one if it finds it, or
create a new entry and insert it in the list with the modification
spin_lock held. incr_count essentially checks the list again and should
return the entry which init_count returned (either the newly created one
or the existing entry). However, what I'm observing is an assertion
which fires in incr_count because it can't find the entry. The only
place where the list is being deleted from is from delete_group.

Having such a scheme what is the correct way to provide synchronization,
it seems that op. 1 and 3 need to be atomic w.r.t to op2? Does this fall
outside of the scope of the RCU protection scheme?