| @@ -2176,15 +2176,37 @@ cache_hit: · 2175 unmodified lines |
| 2176 | 2176 | chain->irq_context = hlock->irq_context; |
| 2177 | 2177 | i = get_first_held_lock(curr, hlock); |
| 2178 | 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 | 2184 | if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { |
| 2180 | 2185 | chain->base = nr_chain_hlocks; |
| 2181 | | − nr_chain_hlocks += chain->depth; |
| 2182 | 2186 | for (j = 0; j < chain->depth - 1; j++, i++) { |
| 2183 | 2187 | int lock_id = curr->held_locks[i].class_idx - 1; |
| 2184 | 2188 | chain_hlocks[chain->base + j] = lock_id; |
| 2185 | 2189 | } |
| 2186 | 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 | 2210 | hlist_add_head_rcu(&chain->entry, hash_head); |
| 2189 | 2211 | debug_atomic_inc(chain_lookup_misses); |
| 2190 | 2212 | inc_chains(); |
| @@ -2932,6 +2954,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) · 741 unmodified lines |
| 2932 | 2954 | return 1; |
| 2933 | 2955 | } |
| 2934 | 2956 | |
| 2957 | +static inline unsigned int task_irq_context(struct task_struct *task) |
| 2958 | +{ |
| 2959 | + return 2 * !!task->hardirq_context + !!task->softirq_context; |
| 2960 | +} |
| 2961 | + |
| 2935 | 2962 | static int separate_irq_context(struct task_struct *curr, |
| 2936 | 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 | 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 | 2970 | if (depth) { |
| 2946 | 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 | 2998 | return 1; |
| 2974 | 2999 | } |
| 2975 | 3000 | |
| 3001 | +static inline unsigned int task_irq_context(struct task_struct *task) |
| 3002 | +{ |
| 3003 | + return 0; |
| 3004 | +} |
| 3005 | + |
| 2976 | 3006 | static inline int separate_irq_context(struct task_struct *curr, |
| 2977 | 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 | 3271 | hlock->acquire_ip = ip; |
| 3242 | 3272 | hlock->instance = lock; |
| 3243 | 3273 | hlock->nest_lock = nest_lock; |
| 3274 | + hlock->irq_context = task_irq_context(curr); |
| 3244 | 3275 | hlock->trylock = trylock; |
| 3245 | 3276 | hlock->read = read; |
| 3246 | 3277 | hlock->check = check; |