Messages in this thread | | | Date | Wed, 3 Oct 2012 01:48:21 +0200 (CEST) | From | Jiri Kosina <> | Subject | Re: Lockdep complains about commit 1331e7a1bb ("rcu: Remove _rcu_barrier() dependency on __stop_machine()") |
| |
On Tue, 2 Oct 2012, Paul E. McKenney wrote:
> Indeed. Slab seems to be doing an rcu_barrier() in a CPU hotplug > notifier, which doesn't sit so well with rcu_barrier() trying to exclude > CPU hotplug events. I could go back to the old approach, but it is > significantly more complex. I cannot say that I am all that happy about > anyone calling rcu_barrier() from a CPU hotplug notifier because it > doesn't help CPU hotplug latency, but that is a separate issue. > > But the thing is that rcu_barrier()'s assumptions work just fine if either > (1) it excludes hotplug operations or (2) if it is called from a hotplug > notifier. You see, either way, the CPU cannot go away while rcu_barrier() > is executing. So the right way to resolve this seems to be to do the > get_online_cpus() only if rcu_barrier() is -not- executing in the context > of a hotplug notifier. Should be fixable without too much hassle...
Sorry, I don't think I understand what you are proposing just yet.
If I understand it correctly, you are proposing to introduce some magic into _rcu_barrier() such as (pseudocode of course):
if (!being_called_from_hotplug_notifier_callback) get_online_cpus()
How does that protect from the scenario I've outlined before though?
CPU 0 CPU 1 kmem_cache_destroy() mutex_lock(slab_mutex) _cpu_up() cpu_hotplug_begin() mutex_lock(cpu_hotplug.lock) rcu_barrier() _rcu_barrier() get_online_cpus() mutex_lock(cpu_hotplug.lock) (blocks, CPU 1 has the mutex) __cpu_notify() mutex_lock(slab_mutex)
CPU 0 grabs both locks anyway (it's not running from notifier callback). CPU 1 grabs both locks as well, as there is no _rcu_barrier() being called from notifier callback either.
What did I miss?
Thanks,
-- Jiri Kosina SUSE Labs
| |