On Sat, Mar 06, 2010 at 09:17:18AM +0800, Herbert Xu wrote:
Agreed, but the callbacks registered by the call_rcu_bh() might run
at any time, possibly quite some time after the synchronize_rcu_bh()
completes. For example, the last call_rcu_bh() might register on
one CPU, and the synchronize_rcu_bh() on another CPU. Then there
is no guarantee that the call_rcu_bh()'s callback will execute before
the synchronize_rcu_bh() returns.
In contrast, rcu_barrier_bh() is guaranteed not to return until all
pending RCU-bh callbacks have executed.
I might simply have missed the operation that removed reader
visibility, looking again...
Ah, I see it. The "br->mdb = NULL" in br_multicast_stop() makes
it impossible for the readers to get to any of the data. Right?
If so, my confusion, you are right, this one is OK.
But spin_lock() does not take the place of rcu_read_lock_bh().
And so, in theory, the RCU-bh grace period could complete between
the time that br_multicast_del_pg() does its call_rcu_bh() and the
"*pp = p->next;" at the top of the next loop iteration. If so,
then br_multicast_free_pg()'s kfree() will possibly have clobbered
"p->next". Low probability, yes, but a long-running interrupt
could do the trick.
Or is there something I am missing that is preventing an RCU-bh
grace period from completing near the bottom of br_multicast_del_pg()'s
"for" loop?
Good!
Hmmm... So the caller is responsible for rcu_read_lock_bh()?
Shouldn't the br_mdb_get() code path be using hlist_for_each_entry_rcu()
in __br_mdb_ip_get(), then? Or is something else going on here?
Thanx, Paul
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html