rcu: Suppress lockdep false positive for rcp->exp_funnel_mutex
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 21 Sep 2015 04:01:22 +0000 (21:01 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 21 Sep 2015 04:01:22 +0000 (21:01 -0700)
In kernels built with CONFIG_PREEMPT=y, synchronize_rcu_expedited()
invokes synchronize_sched_expedited() while holding RCU-preempt's
root rcu_node structure's ->exp_funnel_mutex, which is acquired after
the rcu_data structure's ->exp_funnel_mutex.  The first thing that
synchronize_sched_expedited() will do is acquire RCU-sched's rcu_data
structure's ->exp_funnel_mutex.   There is no danger of an actual deadlock
because the locking order is always from RCU-preempt's expedited mutexes
to those of RCU-sched.  Unfortunately, lockdep considers both rcu_data
structures' ->exp_funnel_mutex to be in the same lock class and therefore
reports a deadlock cycle.

This commit silences this false positive by placing RCU-sched's rcu_data
structures' ->exp_funnel_mutex locks into their own lock class.

Reported-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
kernel/rcu/tree.c

index 9f75f25cc5d92667c27d70dd1b1a6091b42fbceb..775d36cc00506620829bd2ca14b5da21e4de79e3 100644 (file)
@@ -3868,6 +3868,7 @@ static void rcu_init_new_rnp(struct rcu_node *rnp_leaf)
 static void __init
 rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
 {
+       static struct lock_class_key rcu_exp_sched_rdp_class;
        unsigned long flags;
        struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
        struct rcu_node *rnp = rcu_get_root(rsp);
@@ -3883,6 +3884,10 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
        mutex_init(&rdp->exp_funnel_mutex);
        rcu_boot_init_nocb_percpu_data(rdp);
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       if (rsp == &rcu_sched_state)
+               lockdep_set_class_and_name(&rdp->exp_funnel_mutex,
+                                          &rcu_exp_sched_rdp_class,
+                                          "rcu_data_exp_sched");
 }
 
 /*