History

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

Linus Torvalds committed 10 years ago

Commit 2113cae2 parents 8f3603a 75dd6023 files · +41 −6Browse files

Unified · Split

3 files
  1. include/linux/lockdep.h +5 −3
  2. kernel/locking/lockdep.c +34 −3
  3. kernel/locking/lockdep_proc.c +2 −0
include/linux/lockdep.h+5−3
@@ -196,9 +196,11 @@ struct lock_list { · 195 unmodified lines
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};
kernel/locking/lockdep.c+34−3
@@ -2176,15 +2176,37 @@ cache_hit: · 2175 unmodified lines
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) · 741 unmodified lines
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, · 2 unmodified lines
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, · 25 unmodified lines
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, · 262 unmodified lines
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;
kernel/locking/lockdep_proc.c+2−0
@@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v) · 140 unmodified lines
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 }