diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-07-19 18:13:40 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-08-04 11:39:21 -0400 |
commit | af859beaaba4d57883b08f4acbcb3974bc1f975e (patch) | |
tree | 0bff1fa9c43693c9f513daf48197be3627b3301c /kernel/rcu/tree.h | |
parent | cdacbe1f91264687af956e810278030f2ab5a3d0 (diff) |
rcu: Silence lockdep false positive for expedited grace periods
In a CONFIG_PREEMPT=y kernel, synchronize_rcu_expedited()
acquires the ->exp_funnel_mutex in rcu_preempt_state, then invokes
synchronize_sched_expedited, which acquires the ->exp_funnel_mutex in
rcu_sched_state. There can be no deadlock because rcu_preempt_state
->exp_funnel_mutex acquisition always precedes that of rcu_sched_state.
But lockdep does not know that, so it gives false-positive splats.
This commit therefore associates a separate lock_class_key structure
with the rcu_sched_state structure's ->exp_funnel_mutex, allowing
lockdep to see the lock ordering, avoiding the false positives.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.h')
-rw-r--r-- | kernel/rcu/tree.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 80d974df0ea0..0412030ca882 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h | |||
@@ -70,6 +70,8 @@ | |||
70 | # define RCU_NODE_NAME_INIT { "rcu_node_0" } | 70 | # define RCU_NODE_NAME_INIT { "rcu_node_0" } |
71 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0" } | 71 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0" } |
72 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0" } | 72 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0" } |
73 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
74 | { "rcu_node_exp_sched_0" } | ||
73 | #elif NR_CPUS <= RCU_FANOUT_2 | 75 | #elif NR_CPUS <= RCU_FANOUT_2 |
74 | # define RCU_NUM_LVLS 2 | 76 | # define RCU_NUM_LVLS 2 |
75 | # define NUM_RCU_LVL_0 1 | 77 | # define NUM_RCU_LVL_0 1 |
@@ -79,6 +81,8 @@ | |||
79 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1" } | 81 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1" } |
80 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1" } | 82 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1" } |
81 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1" } | 83 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1" } |
84 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
85 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1" } | ||
82 | #elif NR_CPUS <= RCU_FANOUT_3 | 86 | #elif NR_CPUS <= RCU_FANOUT_3 |
83 | # define RCU_NUM_LVLS 3 | 87 | # define RCU_NUM_LVLS 3 |
84 | # define NUM_RCU_LVL_0 1 | 88 | # define NUM_RCU_LVL_0 1 |
@@ -89,6 +93,8 @@ | |||
89 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2" } | 93 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2" } |
90 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2" } | 94 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2" } |
91 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2" } | 95 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2" } |
96 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
97 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1", "rcu_node_exp_sched_2" } | ||
92 | #elif NR_CPUS <= RCU_FANOUT_4 | 98 | #elif NR_CPUS <= RCU_FANOUT_4 |
93 | # define RCU_NUM_LVLS 4 | 99 | # define RCU_NUM_LVLS 4 |
94 | # define NUM_RCU_LVL_0 1 | 100 | # define NUM_RCU_LVL_0 1 |
@@ -100,6 +106,8 @@ | |||
100 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2", "rcu_node_3" } | 106 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2", "rcu_node_3" } |
101 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2", "rcu_node_fqs_3" } | 107 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2", "rcu_node_fqs_3" } |
102 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2", "rcu_node_exp_3" } | 108 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2", "rcu_node_exp_3" } |
109 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
110 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1", "rcu_node_exp_sched_2", "rcu_node_exp_sched_3" } | ||
103 | #else | 111 | #else |
104 | # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" | 112 | # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" |
105 | #endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */ | 113 | #endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */ |