aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 22:59:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 22:59:17 -0400
commit2113caed87dd372e5ca2d9b3cba415f4da38936b (patch)
treea8ce1b6b1653323e11d7152f2900f66bbd4bdca4
parent8f3603a210970d665e7cecf6623331ce6b24f713 (diff)
parent75dd602a5198a6e5f75534db52b6e6fbaabb33d1 (diff)
Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Ingo Molnar: "Two lockdep fixes" * 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: lockdep: Fix lock_chain::base size locking/lockdep: Fix ->irq_context calculation
-rw-r--r--include/linux/lockdep.h8
-rw-r--r--kernel/locking/lockdep.c37
-rw-r--r--kernel/locking/lockdep_proc.c2
3 files changed, 41 insertions, 6 deletions
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index d026b190c530..d10ef06971b5 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -196,9 +196,11 @@ struct lock_list {
196 * We record lock dependency chains, so that we can cache them: 196 * We record lock dependency chains, so that we can cache them:
197 */ 197 */
198struct lock_chain { 198struct lock_chain {
199 u8 irq_context; 199 /* see BUILD_BUG_ON()s in lookup_chain_cache() */
200 u8 depth; 200 unsigned int irq_context : 2,
201 u16 base; 201 depth : 6,
202 base : 24;
203 /* 4 byte hole */
202 struct hlist_node entry; 204 struct hlist_node entry;
203 u64 chain_key; 205 u64 chain_key;
204}; 206};
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index ed9410936a22..78c1c0ee6dc1 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -2176,15 +2176,37 @@ cache_hit:
2176 chain->irq_context = hlock->irq_context; 2176 chain->irq_context = hlock->irq_context;
2177 i = get_first_held_lock(curr, hlock); 2177 i = get_first_held_lock(curr, hlock);
2178 chain->depth = curr->lockdep_depth + 1 - i; 2178 chain->depth = curr->lockdep_depth + 1 - i;
2179
2180 BUILD_BUG_ON((1UL << 24) <= ARRAY_SIZE(chain_hlocks));
2181 BUILD_BUG_ON((1UL << 6) <= ARRAY_SIZE(curr->held_locks));
2182 BUILD_BUG_ON((1UL << 8*sizeof(chain_hlocks[0])) <= ARRAY_SIZE(lock_classes));
2183
2179 if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { 2184 if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) {
2180 chain->base = nr_chain_hlocks; 2185 chain->base = nr_chain_hlocks;
2181 nr_chain_hlocks += chain->depth;
2182 for (j = 0; j < chain->depth - 1; j++, i++) { 2186 for (j = 0; j < chain->depth - 1; j++, i++) {
2183 int lock_id = curr->held_locks[i].class_idx - 1; 2187 int lock_id = curr->held_locks[i].class_idx - 1;
2184 chain_hlocks[chain->base + j] = lock_id; 2188 chain_hlocks[chain->base + j] = lock_id;
2185 } 2189 }
2186 chain_hlocks[chain->base + j] = class - lock_classes; 2190 chain_hlocks[chain->base + j] = class - lock_classes;
2187 } 2191 }
2192
2193 if (nr_chain_hlocks < MAX_LOCKDEP_CHAIN_HLOCKS)
2194 nr_chain_hlocks += chain->depth;
2195
2196#ifdef CONFIG_DEBUG_LOCKDEP
2197 /*
2198 * Important for check_no_collision().
2199 */
2200 if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) {
2201 if (debug_locks_off_graph_unlock())
2202 return 0;
2203
2204 print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!");
2205 dump_stack();
2206 return 0;
2207 }
2208#endif
2209
2188 hlist_add_head_rcu(&chain->entry, hash_head); 2210 hlist_add_head_rcu(&chain->entry, hash_head);
2189 debug_atomic_inc(chain_lookup_misses); 2211 debug_atomic_inc(chain_lookup_misses);
2190 inc_chains(); 2212 inc_chains();
@@ -2932,6 +2954,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock)
2932 return 1; 2954 return 1;
2933} 2955}
2934 2956
2957static inline unsigned int task_irq_context(struct task_struct *task)
2958{
2959 return 2 * !!task->hardirq_context + !!task->softirq_context;
2960}
2961
2935static int separate_irq_context(struct task_struct *curr, 2962static int separate_irq_context(struct task_struct *curr,
2936 struct held_lock *hlock) 2963 struct held_lock *hlock)
2937{ 2964{
@@ -2940,8 +2967,6 @@ static int separate_irq_context(struct task_struct *curr,
2940 /* 2967 /*
2941 * Keep track of points where we cross into an interrupt context: 2968 * Keep track of points where we cross into an interrupt context:
2942 */ 2969 */
2943 hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) +
2944 curr->softirq_context;
2945 if (depth) { 2970 if (depth) {
2946 struct held_lock *prev_hlock; 2971 struct held_lock *prev_hlock;
2947 2972
@@ -2973,6 +2998,11 @@ static inline int mark_irqflags(struct task_struct *curr,
2973 return 1; 2998 return 1;
2974} 2999}
2975 3000
3001static inline unsigned int task_irq_context(struct task_struct *task)
3002{
3003 return 0;
3004}
3005
2976static inline int separate_irq_context(struct task_struct *curr, 3006static inline int separate_irq_context(struct task_struct *curr,
2977 struct held_lock *hlock) 3007 struct held_lock *hlock)
2978{ 3008{
@@ -3241,6 +3271,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
3241 hlock->acquire_ip = ip; 3271 hlock->acquire_ip = ip;
3242 hlock->instance = lock; 3272 hlock->instance = lock;
3243 hlock->nest_lock = nest_lock; 3273 hlock->nest_lock = nest_lock;
3274 hlock->irq_context = task_irq_context(curr);
3244 hlock->trylock = trylock; 3275 hlock->trylock = trylock;
3245 hlock->read = read; 3276 hlock->read = read;
3246 hlock->check = check; 3277 hlock->check = check;
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c
index dbb61a302548..a0f61effad25 100644
--- a/kernel/locking/lockdep_proc.c
+++ b/kernel/locking/lockdep_proc.c
@@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v)
141 int i; 141 int i;
142 142
143 if (v == SEQ_START_TOKEN) { 143 if (v == SEQ_START_TOKEN) {
144 if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)
145 seq_printf(m, "(buggered) ");
144 seq_printf(m, "all lock chains:\n"); 146 seq_printf(m, "all lock chains:\n");
145 return 0; 147 return 0;
146 } 148 }