On Mon, Sep 11, 2017 at 2:14 PM, Cong Wang [off-list ref] wrote:
Looks like all due to the lack of locking on block->chain_list.
I thought the rcu_barrier() could properly handle this,
but seems still not, probably I need to move it in the loop,
I am still not 100% sure if it is totally safe with
list_for_each_safe():
- list_for_each_entry(chain, &block->chain_list, list)
+ list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
tcf_chain_flush(chain);
- rcu_barrier();
+ rcu_barrier(); // are we safe now???
+ }
Answer myself: No, this is not safe either, because we may
list_del() the next node, and apparently _safe() can't guarantee
that...
So either we have to use locking or use the trick you suggested.