Loading arch/arm64/configs/vendor/kona_defconfig +1 −0 Original line number Diff line number Diff line Loading @@ -740,6 +740,7 @@ CONFIG_PANIC_ON_RT_THROTTLING=y CONFIG_SCHEDSTATS=y CONFIG_SCHED_STACK_END_CHECK=y CONFIG_PROVE_LOCKING=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_LOCK_TORTURE_TEST=m CONFIG_DEBUG_SG=y Loading include/linux/lockdep.h +2 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ struct lockdep_map { #ifdef CONFIG_LOCK_STAT int cpu; unsigned long ip; unsigned long ip_caller; #endif }; Loading Loading @@ -233,6 +234,7 @@ struct held_lock { */ u64 prev_chain_key; unsigned long acquire_ip; unsigned long acquire_ip_caller; struct lockdep_map *instance; struct lockdep_map *nest_lock; #ifdef CONFIG_LOCK_STAT Loading kernel/locking/lockdep.c +149 −69 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #include <linux/nmi.h> #include <asm/sections.h> #include <asm/stacktrace.h> #include "lockdep_internals.h" Loading @@ -72,6 +73,30 @@ module_param(lock_stat, int, 0644); #define lock_stat 0 #endif static int lockdep_log = 1; static int lockdep_logging_off(void) { if (lockdep_log && xchg(&lockdep_log, 0)) { if (!debug_locks_silent) return 1; } return 0; } #define MAX_ITR 20 #define lockdep_warn_on(cond) \ ({ \ int __ret = 0; \ \ if (!oops_in_progress && unlikely(cond)) { \ if (lockdep_logging_off() && !debug_locks_silent) \ WARN(1, "lockdep_warn_on(%s)", #cond); \ __ret = 1; \ } \ __ret; \ }) /* * lockdep_lock: protects the lockdep graph, the hashes and the * class/list/hash allocators. Loading Loading @@ -107,7 +132,7 @@ static inline int graph_unlock(void) * The lockdep graph lock isn't locked while we expect it to * be, we're confused now, bye! */ return DEBUG_LOCKS_WARN_ON(1); return lockdep_warn_on(1); } current->lockdep_recursion--; Loading @@ -115,6 +140,14 @@ static inline int graph_unlock(void) return 0; } static int lockdep_logging_off_graph_unlock(void) { int ret = lockdep_logging_off(); graph_unlock(); return ret; } /* * Turn lock debugging off and return with 0 if it was off already, * and also release the graph lock: Loading Loading @@ -146,7 +179,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) /* * Someone passed in garbage, we give up. */ DEBUG_LOCKS_WARN_ON(1); lockdep_warn_on(1); return NULL; } return lock_classes + hlock->class_idx - 1; Loading Loading @@ -413,7 +446,7 @@ static int save_trace(struct stack_trace *trace) nr_stack_trace_entries += trace->nr_entries; if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES-1) { if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); Loading Loading @@ -720,10 +753,8 @@ static bool assign_lock_key(struct lockdep_map *lock) lock->key = (void *)lock; else { /* Debug-check: all keys must be persistent! */ debug_locks_off(); pr_err("INFO: trying to register non-static key.\n"); pr_err("the code is fine but needs lockdep annotation.\n"); pr_err("turning off the locking correctness validator.\n"); dump_stack(); return false; } Loading Loading @@ -1193,7 +1224,7 @@ static noinline int print_circular_bug(struct lock_list *this, struct lock_list *first_parent; int depth; if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; if (!save_trace(&this->trace)) Loading Loading @@ -1508,7 +1539,7 @@ print_bad_irq_dependency(struct task_struct *curr, enum lock_usage_bit bit2, const char *irqclass) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -1737,7 +1768,7 @@ static int print_deadlock_bug(struct task_struct *curr, struct held_lock *prev, struct held_lock *next) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2000,7 +2031,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) } return 1; out_bug: if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; /* Loading Loading @@ -2130,7 +2161,7 @@ static int check_no_collision(struct task_struct *curr, i = get_first_held_lock(curr, hlock); if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) { if (lockdep_warn_on(chain->depth != curr->lockdep_depth - (i - 1))) { print_collision(curr, hlock, chain); return 0; } Loading @@ -2138,7 +2169,7 @@ static int check_no_collision(struct task_struct *curr, for (j = 0; j < chain->depth - 1; j++, i++) { id = curr->held_locks[i].class_idx - 1; if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) { if (lockdep_warn_on(chain_hlocks[chain->base + j] != id)) { print_collision(curr, hlock, chain); return 0; } Loading Loading @@ -2399,7 +2430,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, int ret = check_deadlock(curr, hlock, lock, hlock->read); if (!ret) return 0; return 1; /* * Mark recursive read, as we jump over it when * building dependencies (just like we jump over Loading @@ -2413,7 +2444,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, */ if (!chain_head && ret != 2) { if (!check_prevs_add(curr, hlock)) return 0; return 1; } graph_unlock(); Loading Loading @@ -2507,7 +2538,7 @@ static int print_usage_bug(struct task_struct *curr, struct held_lock *this, enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2572,7 +2603,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_list *middle = NULL; int depth; if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2992,40 +3023,41 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) if (curr->hardirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ_READ)) return 0; goto out; if (curr->softirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ_READ)) return 0; goto out; } else { if (curr->hardirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ)) return 0; goto out; if (curr->softirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ)) return 0; goto out; } } if (!hlock->hardirqs_off) { if (hlock->read) { if (!mark_lock(curr, hlock, LOCK_ENABLED_HARDIRQ_READ)) return 0; goto out; if (curr->softirqs_enabled) if (!mark_lock(curr, hlock, LOCK_ENABLED_SOFTIRQ_READ)) return 0; goto out; } else { if (!mark_lock(curr, hlock, LOCK_ENABLED_HARDIRQ)) return 0; goto out; if (curr->softirqs_enabled) if (!mark_lock(curr, hlock, LOCK_ENABLED_SOFTIRQ)) return 0; goto out; } } out: return 1; } Loading Loading @@ -3132,7 +3164,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, debug_atomic_dec(nr_unused_locks); break; default: if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; WARN_ON(1); return 0; Loading Loading @@ -3171,7 +3203,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, /* * Can't be having no nameless bastards around this place! */ if (DEBUG_LOCKS_WARN_ON(!name)) { if (lockdep_warn_on(!name)) { lock->name = "NULL"; return; } Loading @@ -3181,17 +3213,22 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, /* * No key, no joy, we need to hash something. */ if (DEBUG_LOCKS_WARN_ON(!key)) if (lockdep_warn_on(!key)) return; /* * Sanity check, the lock-class key must be persistent: */ if (!static_obj(key)) { /* * to make sure register_lock_class returns NULL * for a non static key */ lock->key = key; printk("BUG: key %px not in .data!\n", key); /* * What it says above ^^^^^, I suggest you read it. */ DEBUG_LOCKS_WARN_ON(1); lockdep_warn_on(1); return; } lock->key = key; Loading @@ -3202,7 +3239,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, if (subclass) { unsigned long flags; if (DEBUG_LOCKS_WARN_ON(current->lockdep_recursion)) if (lockdep_warn_on(current->lockdep_recursion)) return; raw_local_irq_save(flags); Loading @@ -3228,9 +3265,7 @@ print_lock_nested_lock_not_held(struct task_struct *curr, struct held_lock *hlock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -3259,6 +3294,33 @@ print_lock_nested_lock_not_held(struct task_struct *curr, static int __lock_is_held(const struct lockdep_map *lock, int read); static unsigned long lockdep_walk_stack(unsigned long addr) { int ret; struct stackframe frame; struct task_struct *tsk = current; bool end_search = false; int counter = 0; frame.fp = (unsigned long)__builtin_frame_address(0); frame.pc = (unsigned long)lockdep_walk_stack; while (counter < MAX_ITR) { counter++; if (frame.pc == addr) end_search = true; ret = unwind_frame(tsk, &frame); if ((ret < 0) || end_search) break; } if (unlikely(ret < 0) || unlikely(counter == MAX_ITR)) return 0; else return frame.pc; } /* * This gets called for every mutex_lock*()/spin_lock*() operation. * We maintain the dependency maps and validate the locking attempt: Loading @@ -3266,7 +3328,8 @@ static int __lock_is_held(const struct lockdep_map *lock, int read); static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, int trylock, int read, int check, int hardirqs_off, struct lockdep_map *nest_lock, unsigned long ip, int references, int pin_count) int references, int pin_count, unsigned long ip_caller) { struct task_struct *curr = current; struct lock_class *class = NULL; Loading Loading @@ -3347,7 +3410,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, * Plain impossible, we just registered it and checked it weren't no * NULL like.. I bet this mushroom I ate was good! */ if (DEBUG_LOCKS_WARN_ON(!class)) if (lockdep_warn_on(!class)) return 0; hlock->class_idx = class_idx; hlock->acquire_ip = ip; Loading @@ -3364,13 +3427,16 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, hlock->holdtime_stamp = lockstat_clock(); #endif hlock->pin_count = pin_count; if (!ip_caller) hlock->acquire_ip_caller = lockdep_walk_stack(ip); else hlock->acquire_ip_caller = ip_caller; if (check && !mark_irqflags(curr, hlock)) return 0; /* mark it as used: */ if (!mark_lock(curr, hlock, LOCK_USED)) return 0; mark_lock(curr, hlock, LOCK_USED); /* * Calculate the chain hash: it's the combined hash of all the Loading @@ -3393,7 +3459,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, /* * How can we have a chain hash when we ain't got no keys?! */ if (DEBUG_LOCKS_WARN_ON(chain_key != 0)) if (lockdep_warn_on(chain_key != 0)) return 0; chain_head = 1; } Loading Loading @@ -3441,9 +3507,7 @@ static int print_unlock_imbalance_bug(struct task_struct *curr, struct lockdep_map *lock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -3492,7 +3556,7 @@ static int match_held_lock(const struct held_lock *hlock, * State got messed up, follow the sites that change ->references * and try to make sense of it. */ if (DEBUG_LOCKS_WARN_ON(!hlock->nest_lock)) if (lockdep_warn_on(!hlock->nest_lock)) return 0; if (hlock->class_idx == class - lock_classes + 1) Loading Loading @@ -3550,7 +3614,8 @@ static int reacquire_held_locks(struct task_struct *curr, unsigned int depth, hlock->read, hlock->check, hlock->hardirqs_off, hlock->nest_lock, hlock->acquire_ip, hlock->references, hlock->pin_count)) hlock->references, hlock->pin_count, hlock->acquire_ip_caller)) return 1; } return 0; Loading @@ -3572,7 +3637,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name, * This function is about (re)setting the class of a held lock, * yet we're not actually holding any locks. Naughty user! */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return 0; hlock = find_held_lock(curr, lock, depth, &i); Loading @@ -3581,6 +3646,9 @@ __lock_set_class(struct lockdep_map *lock, const char *name, lockdep_init_map(lock, name, key, 0); class = register_lock_class(lock, subclass, 0); if (!class) return 0; hlock->class_idx = class - lock_classes + 1; curr->lockdep_depth = i; Loading @@ -3593,7 +3661,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name, * I took it apart and put it back together again, except now I have * these 'spare' parts.. where shall I put them. */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth)) if (lockdep_warn_on(curr->lockdep_depth != depth)) return 0; return 1; } Loading @@ -3613,7 +3681,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) * This function is about (re)setting the class of a held lock, * yet we're not actually holding any locks. Naughty user! */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return 0; hlock = find_held_lock(curr, lock, depth, &i); Loading @@ -3623,9 +3691,12 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) curr->lockdep_depth = i; curr->curr_chain_key = hlock->prev_chain_key; if (lockdep_logging_off()) WARN(hlock->read, "downgrading a read lock"); hlock->read = 1; hlock->acquire_ip = ip; hlock->acquire_ip_caller = lockdep_walk_stack(ip); if (reacquire_held_locks(curr, depth, i)) return 0; Loading @@ -3634,7 +3705,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) * I took it apart and put it back together again, except now I have * these 'spare' parts.. where shall I put them. */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth)) if (lockdep_warn_on(curr->lockdep_depth != depth)) return 0; return 1; } Loading Loading @@ -3662,7 +3733,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) * So we're all set to release this lock.. wait what lock? We don't * own any locks, you've been drinking again? */ if (DEBUG_LOCKS_WARN_ON(depth <= 0)) if (lockdep_warn_on(depth <= 0)) return print_unlock_imbalance_bug(curr, lock, ip); /* Loading @@ -3676,6 +3747,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) if (hlock->instance == lock) lock_release_holdtime(hlock); if (lockdep_logging_off()) WARN(hlock->pin_count, "releasing a pinned lock\n"); if (hlock->references) { Loading Loading @@ -3706,7 +3778,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) * We had N bottles of beer on the wall, we drank one, but now * there's not N-1 bottles of beer left on the wall... */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth - 1)) if (lockdep_warn_on(curr->lockdep_depth != depth - 1)) return 0; return 1; Loading Loading @@ -3755,7 +3827,9 @@ static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock) } } if (lockdep_logging_off()) WARN(1, "pinning an unheld lock\n"); return cookie; } Loading @@ -3776,6 +3850,7 @@ static void __lock_repin_lock(struct lockdep_map *lock, struct pin_cookie cookie } } if (lockdep_logging_off()) WARN(1, "pinning an unheld lock\n"); } Loading @@ -3791,18 +3866,25 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie struct held_lock *hlock = curr->held_locks + i; if (match_held_lock(hlock, lock)) { if (WARN(!hlock->pin_count, "unpinning an unpinned lock\n")) if (!hlock->pin_count) { if (lockdep_logging_off()) WARN(1, "unpinning an unpinned lock\n"); return; } hlock->pin_count -= cookie.val; if (WARN((int)hlock->pin_count < 0, "pin count corrupted\n")) if ((int)hlock->pin_count < 0) { if (lockdep_logging_off()) WARN(1, "pin count corrupted\n"); hlock->pin_count = 0; } return; } } if (lockdep_logging_off()) WARN(1, "unpinning an unheld lock\n"); } Loading Loading @@ -3901,7 +3983,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, current->lockdep_recursion = 1; trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); __lock_acquire(lock, subclass, trylock, read, check, irqs_disabled_flags(flags), nest_lock, ip, 0, 0); irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0); current->lockdep_recursion = 0; raw_local_irq_restore(flags); } Loading Loading @@ -4005,9 +4087,7 @@ static int print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -4044,7 +4124,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) * Whee, we contended on this lock, except it seems we're not * actually trying to acquire anything much at all.. */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return; hlock = find_held_lock(curr, lock, depth, &i); Loading Loading @@ -4086,7 +4166,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip) * Yay, we acquired ownership of this lock we didn't try to * acquire, how the heck did that happen? */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return; hlock = find_held_lock(curr, lock, depth, &i); Loading Loading @@ -4119,6 +4199,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip) lock->cpu = cpu; lock->ip = ip; lock->ip_caller = lockdep_walk_stack(ip); } void lock_contended(struct lockdep_map *lock, unsigned long ip) Loading Loading @@ -4298,7 +4379,7 @@ void lockdep_reset_lock(struct lockdep_map *lock) match |= class == lock->class_cache[j]; if (unlikely(match)) { if (debug_locks_off_graph_unlock()) { if (lockdep_logging_off_graph_unlock()) { /* * We all just reset everything, how did it match? */ Loading Loading @@ -4347,9 +4428,7 @@ static void print_freed_lock_bug(struct task_struct *curr, const void *mem_from, const void *mem_to, struct held_lock *hlock) { if (!debug_locks_off()) return; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return; pr_warn("\n"); Loading Loading @@ -4405,9 +4484,7 @@ EXPORT_SYMBOL_GPL(debug_check_no_locks_freed); static void print_held_locks_bug(void) { if (!debug_locks_off()) return; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return; pr_warn("\n"); Loading Loading @@ -4474,7 +4551,7 @@ asmlinkage __visible void lockdep_sys_exit(void) struct task_struct *curr = current; if (unlikely(curr->lockdep_depth)) { if (!debug_locks_off()) if (!lockdep_logging_off()) return; pr_warn("\n"); pr_warn("================================================\n"); Loading @@ -4497,6 +4574,9 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s) { struct task_struct *curr = current; if (!lockdep_logging_off()) return; /* Note: the following can be executed concurrently, so be careful. */ pr_warn("\n"); pr_warn("=============================\n"); Loading Loading
arch/arm64/configs/vendor/kona_defconfig +1 −0 Original line number Diff line number Diff line Loading @@ -740,6 +740,7 @@ CONFIG_PANIC_ON_RT_THROTTLING=y CONFIG_SCHEDSTATS=y CONFIG_SCHED_STACK_END_CHECK=y CONFIG_PROVE_LOCKING=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_LOCK_TORTURE_TEST=m CONFIG_DEBUG_SG=y Loading
include/linux/lockdep.h +2 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ struct lockdep_map { #ifdef CONFIG_LOCK_STAT int cpu; unsigned long ip; unsigned long ip_caller; #endif }; Loading Loading @@ -233,6 +234,7 @@ struct held_lock { */ u64 prev_chain_key; unsigned long acquire_ip; unsigned long acquire_ip_caller; struct lockdep_map *instance; struct lockdep_map *nest_lock; #ifdef CONFIG_LOCK_STAT Loading
kernel/locking/lockdep.c +149 −69 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #include <linux/nmi.h> #include <asm/sections.h> #include <asm/stacktrace.h> #include "lockdep_internals.h" Loading @@ -72,6 +73,30 @@ module_param(lock_stat, int, 0644); #define lock_stat 0 #endif static int lockdep_log = 1; static int lockdep_logging_off(void) { if (lockdep_log && xchg(&lockdep_log, 0)) { if (!debug_locks_silent) return 1; } return 0; } #define MAX_ITR 20 #define lockdep_warn_on(cond) \ ({ \ int __ret = 0; \ \ if (!oops_in_progress && unlikely(cond)) { \ if (lockdep_logging_off() && !debug_locks_silent) \ WARN(1, "lockdep_warn_on(%s)", #cond); \ __ret = 1; \ } \ __ret; \ }) /* * lockdep_lock: protects the lockdep graph, the hashes and the * class/list/hash allocators. Loading Loading @@ -107,7 +132,7 @@ static inline int graph_unlock(void) * The lockdep graph lock isn't locked while we expect it to * be, we're confused now, bye! */ return DEBUG_LOCKS_WARN_ON(1); return lockdep_warn_on(1); } current->lockdep_recursion--; Loading @@ -115,6 +140,14 @@ static inline int graph_unlock(void) return 0; } static int lockdep_logging_off_graph_unlock(void) { int ret = lockdep_logging_off(); graph_unlock(); return ret; } /* * Turn lock debugging off and return with 0 if it was off already, * and also release the graph lock: Loading Loading @@ -146,7 +179,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) /* * Someone passed in garbage, we give up. */ DEBUG_LOCKS_WARN_ON(1); lockdep_warn_on(1); return NULL; } return lock_classes + hlock->class_idx - 1; Loading Loading @@ -413,7 +446,7 @@ static int save_trace(struct stack_trace *trace) nr_stack_trace_entries += trace->nr_entries; if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES-1) { if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); Loading Loading @@ -720,10 +753,8 @@ static bool assign_lock_key(struct lockdep_map *lock) lock->key = (void *)lock; else { /* Debug-check: all keys must be persistent! */ debug_locks_off(); pr_err("INFO: trying to register non-static key.\n"); pr_err("the code is fine but needs lockdep annotation.\n"); pr_err("turning off the locking correctness validator.\n"); dump_stack(); return false; } Loading Loading @@ -1193,7 +1224,7 @@ static noinline int print_circular_bug(struct lock_list *this, struct lock_list *first_parent; int depth; if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; if (!save_trace(&this->trace)) Loading Loading @@ -1508,7 +1539,7 @@ print_bad_irq_dependency(struct task_struct *curr, enum lock_usage_bit bit2, const char *irqclass) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -1737,7 +1768,7 @@ static int print_deadlock_bug(struct task_struct *curr, struct held_lock *prev, struct held_lock *next) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2000,7 +2031,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) } return 1; out_bug: if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; /* Loading Loading @@ -2130,7 +2161,7 @@ static int check_no_collision(struct task_struct *curr, i = get_first_held_lock(curr, hlock); if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) { if (lockdep_warn_on(chain->depth != curr->lockdep_depth - (i - 1))) { print_collision(curr, hlock, chain); return 0; } Loading @@ -2138,7 +2169,7 @@ static int check_no_collision(struct task_struct *curr, for (j = 0; j < chain->depth - 1; j++, i++) { id = curr->held_locks[i].class_idx - 1; if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) { if (lockdep_warn_on(chain_hlocks[chain->base + j] != id)) { print_collision(curr, hlock, chain); return 0; } Loading Loading @@ -2399,7 +2430,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, int ret = check_deadlock(curr, hlock, lock, hlock->read); if (!ret) return 0; return 1; /* * Mark recursive read, as we jump over it when * building dependencies (just like we jump over Loading @@ -2413,7 +2444,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, */ if (!chain_head && ret != 2) { if (!check_prevs_add(curr, hlock)) return 0; return 1; } graph_unlock(); Loading Loading @@ -2507,7 +2538,7 @@ static int print_usage_bug(struct task_struct *curr, struct held_lock *this, enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit) { if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2572,7 +2603,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_list *middle = NULL; int depth; if (!debug_locks_off_graph_unlock() || debug_locks_silent) if (!lockdep_logging_off_graph_unlock() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -2992,40 +3023,41 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) if (curr->hardirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ_READ)) return 0; goto out; if (curr->softirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ_READ)) return 0; goto out; } else { if (curr->hardirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ)) return 0; goto out; if (curr->softirq_context) if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ)) return 0; goto out; } } if (!hlock->hardirqs_off) { if (hlock->read) { if (!mark_lock(curr, hlock, LOCK_ENABLED_HARDIRQ_READ)) return 0; goto out; if (curr->softirqs_enabled) if (!mark_lock(curr, hlock, LOCK_ENABLED_SOFTIRQ_READ)) return 0; goto out; } else { if (!mark_lock(curr, hlock, LOCK_ENABLED_HARDIRQ)) return 0; goto out; if (curr->softirqs_enabled) if (!mark_lock(curr, hlock, LOCK_ENABLED_SOFTIRQ)) return 0; goto out; } } out: return 1; } Loading Loading @@ -3132,7 +3164,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, debug_atomic_dec(nr_unused_locks); break; default: if (!debug_locks_off_graph_unlock()) if (!lockdep_logging_off_graph_unlock()) return 0; WARN_ON(1); return 0; Loading Loading @@ -3171,7 +3203,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, /* * Can't be having no nameless bastards around this place! */ if (DEBUG_LOCKS_WARN_ON(!name)) { if (lockdep_warn_on(!name)) { lock->name = "NULL"; return; } Loading @@ -3181,17 +3213,22 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, /* * No key, no joy, we need to hash something. */ if (DEBUG_LOCKS_WARN_ON(!key)) if (lockdep_warn_on(!key)) return; /* * Sanity check, the lock-class key must be persistent: */ if (!static_obj(key)) { /* * to make sure register_lock_class returns NULL * for a non static key */ lock->key = key; printk("BUG: key %px not in .data!\n", key); /* * What it says above ^^^^^, I suggest you read it. */ DEBUG_LOCKS_WARN_ON(1); lockdep_warn_on(1); return; } lock->key = key; Loading @@ -3202,7 +3239,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, if (subclass) { unsigned long flags; if (DEBUG_LOCKS_WARN_ON(current->lockdep_recursion)) if (lockdep_warn_on(current->lockdep_recursion)) return; raw_local_irq_save(flags); Loading @@ -3228,9 +3265,7 @@ print_lock_nested_lock_not_held(struct task_struct *curr, struct held_lock *hlock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -3259,6 +3294,33 @@ print_lock_nested_lock_not_held(struct task_struct *curr, static int __lock_is_held(const struct lockdep_map *lock, int read); static unsigned long lockdep_walk_stack(unsigned long addr) { int ret; struct stackframe frame; struct task_struct *tsk = current; bool end_search = false; int counter = 0; frame.fp = (unsigned long)__builtin_frame_address(0); frame.pc = (unsigned long)lockdep_walk_stack; while (counter < MAX_ITR) { counter++; if (frame.pc == addr) end_search = true; ret = unwind_frame(tsk, &frame); if ((ret < 0) || end_search) break; } if (unlikely(ret < 0) || unlikely(counter == MAX_ITR)) return 0; else return frame.pc; } /* * This gets called for every mutex_lock*()/spin_lock*() operation. * We maintain the dependency maps and validate the locking attempt: Loading @@ -3266,7 +3328,8 @@ static int __lock_is_held(const struct lockdep_map *lock, int read); static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, int trylock, int read, int check, int hardirqs_off, struct lockdep_map *nest_lock, unsigned long ip, int references, int pin_count) int references, int pin_count, unsigned long ip_caller) { struct task_struct *curr = current; struct lock_class *class = NULL; Loading Loading @@ -3347,7 +3410,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, * Plain impossible, we just registered it and checked it weren't no * NULL like.. I bet this mushroom I ate was good! */ if (DEBUG_LOCKS_WARN_ON(!class)) if (lockdep_warn_on(!class)) return 0; hlock->class_idx = class_idx; hlock->acquire_ip = ip; Loading @@ -3364,13 +3427,16 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, hlock->holdtime_stamp = lockstat_clock(); #endif hlock->pin_count = pin_count; if (!ip_caller) hlock->acquire_ip_caller = lockdep_walk_stack(ip); else hlock->acquire_ip_caller = ip_caller; if (check && !mark_irqflags(curr, hlock)) return 0; /* mark it as used: */ if (!mark_lock(curr, hlock, LOCK_USED)) return 0; mark_lock(curr, hlock, LOCK_USED); /* * Calculate the chain hash: it's the combined hash of all the Loading @@ -3393,7 +3459,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, /* * How can we have a chain hash when we ain't got no keys?! */ if (DEBUG_LOCKS_WARN_ON(chain_key != 0)) if (lockdep_warn_on(chain_key != 0)) return 0; chain_head = 1; } Loading Loading @@ -3441,9 +3507,7 @@ static int print_unlock_imbalance_bug(struct task_struct *curr, struct lockdep_map *lock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -3492,7 +3556,7 @@ static int match_held_lock(const struct held_lock *hlock, * State got messed up, follow the sites that change ->references * and try to make sense of it. */ if (DEBUG_LOCKS_WARN_ON(!hlock->nest_lock)) if (lockdep_warn_on(!hlock->nest_lock)) return 0; if (hlock->class_idx == class - lock_classes + 1) Loading Loading @@ -3550,7 +3614,8 @@ static int reacquire_held_locks(struct task_struct *curr, unsigned int depth, hlock->read, hlock->check, hlock->hardirqs_off, hlock->nest_lock, hlock->acquire_ip, hlock->references, hlock->pin_count)) hlock->references, hlock->pin_count, hlock->acquire_ip_caller)) return 1; } return 0; Loading @@ -3572,7 +3637,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name, * This function is about (re)setting the class of a held lock, * yet we're not actually holding any locks. Naughty user! */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return 0; hlock = find_held_lock(curr, lock, depth, &i); Loading @@ -3581,6 +3646,9 @@ __lock_set_class(struct lockdep_map *lock, const char *name, lockdep_init_map(lock, name, key, 0); class = register_lock_class(lock, subclass, 0); if (!class) return 0; hlock->class_idx = class - lock_classes + 1; curr->lockdep_depth = i; Loading @@ -3593,7 +3661,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name, * I took it apart and put it back together again, except now I have * these 'spare' parts.. where shall I put them. */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth)) if (lockdep_warn_on(curr->lockdep_depth != depth)) return 0; return 1; } Loading @@ -3613,7 +3681,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) * This function is about (re)setting the class of a held lock, * yet we're not actually holding any locks. Naughty user! */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return 0; hlock = find_held_lock(curr, lock, depth, &i); Loading @@ -3623,9 +3691,12 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) curr->lockdep_depth = i; curr->curr_chain_key = hlock->prev_chain_key; if (lockdep_logging_off()) WARN(hlock->read, "downgrading a read lock"); hlock->read = 1; hlock->acquire_ip = ip; hlock->acquire_ip_caller = lockdep_walk_stack(ip); if (reacquire_held_locks(curr, depth, i)) return 0; Loading @@ -3634,7 +3705,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip) * I took it apart and put it back together again, except now I have * these 'spare' parts.. where shall I put them. */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth)) if (lockdep_warn_on(curr->lockdep_depth != depth)) return 0; return 1; } Loading Loading @@ -3662,7 +3733,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) * So we're all set to release this lock.. wait what lock? We don't * own any locks, you've been drinking again? */ if (DEBUG_LOCKS_WARN_ON(depth <= 0)) if (lockdep_warn_on(depth <= 0)) return print_unlock_imbalance_bug(curr, lock, ip); /* Loading @@ -3676,6 +3747,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) if (hlock->instance == lock) lock_release_holdtime(hlock); if (lockdep_logging_off()) WARN(hlock->pin_count, "releasing a pinned lock\n"); if (hlock->references) { Loading Loading @@ -3706,7 +3778,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) * We had N bottles of beer on the wall, we drank one, but now * there's not N-1 bottles of beer left on the wall... */ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth - 1)) if (lockdep_warn_on(curr->lockdep_depth != depth - 1)) return 0; return 1; Loading Loading @@ -3755,7 +3827,9 @@ static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock) } } if (lockdep_logging_off()) WARN(1, "pinning an unheld lock\n"); return cookie; } Loading @@ -3776,6 +3850,7 @@ static void __lock_repin_lock(struct lockdep_map *lock, struct pin_cookie cookie } } if (lockdep_logging_off()) WARN(1, "pinning an unheld lock\n"); } Loading @@ -3791,18 +3866,25 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie struct held_lock *hlock = curr->held_locks + i; if (match_held_lock(hlock, lock)) { if (WARN(!hlock->pin_count, "unpinning an unpinned lock\n")) if (!hlock->pin_count) { if (lockdep_logging_off()) WARN(1, "unpinning an unpinned lock\n"); return; } hlock->pin_count -= cookie.val; if (WARN((int)hlock->pin_count < 0, "pin count corrupted\n")) if ((int)hlock->pin_count < 0) { if (lockdep_logging_off()) WARN(1, "pin count corrupted\n"); hlock->pin_count = 0; } return; } } if (lockdep_logging_off()) WARN(1, "unpinning an unheld lock\n"); } Loading Loading @@ -3901,7 +3983,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, current->lockdep_recursion = 1; trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); __lock_acquire(lock, subclass, trylock, read, check, irqs_disabled_flags(flags), nest_lock, ip, 0, 0); irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0); current->lockdep_recursion = 0; raw_local_irq_restore(flags); } Loading Loading @@ -4005,9 +4087,7 @@ static int print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, unsigned long ip) { if (!debug_locks_off()) return 0; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return 0; pr_warn("\n"); Loading Loading @@ -4044,7 +4124,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) * Whee, we contended on this lock, except it seems we're not * actually trying to acquire anything much at all.. */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return; hlock = find_held_lock(curr, lock, depth, &i); Loading Loading @@ -4086,7 +4166,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip) * Yay, we acquired ownership of this lock we didn't try to * acquire, how the heck did that happen? */ if (DEBUG_LOCKS_WARN_ON(!depth)) if (lockdep_warn_on(!depth)) return; hlock = find_held_lock(curr, lock, depth, &i); Loading Loading @@ -4119,6 +4199,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip) lock->cpu = cpu; lock->ip = ip; lock->ip_caller = lockdep_walk_stack(ip); } void lock_contended(struct lockdep_map *lock, unsigned long ip) Loading Loading @@ -4298,7 +4379,7 @@ void lockdep_reset_lock(struct lockdep_map *lock) match |= class == lock->class_cache[j]; if (unlikely(match)) { if (debug_locks_off_graph_unlock()) { if (lockdep_logging_off_graph_unlock()) { /* * We all just reset everything, how did it match? */ Loading Loading @@ -4347,9 +4428,7 @@ static void print_freed_lock_bug(struct task_struct *curr, const void *mem_from, const void *mem_to, struct held_lock *hlock) { if (!debug_locks_off()) return; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return; pr_warn("\n"); Loading Loading @@ -4405,9 +4484,7 @@ EXPORT_SYMBOL_GPL(debug_check_no_locks_freed); static void print_held_locks_bug(void) { if (!debug_locks_off()) return; if (debug_locks_silent) if (!lockdep_logging_off() || debug_locks_silent) return; pr_warn("\n"); Loading Loading @@ -4474,7 +4551,7 @@ asmlinkage __visible void lockdep_sys_exit(void) struct task_struct *curr = current; if (unlikely(curr->lockdep_depth)) { if (!debug_locks_off()) if (!lockdep_logging_off()) return; pr_warn("\n"); pr_warn("================================================\n"); Loading @@ -4497,6 +4574,9 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s) { struct task_struct *curr = current; if (!lockdep_logging_off()) return; /* Note: the following can be executed concurrently, so be careful. */ pr_warn("\n"); pr_warn("=============================\n"); Loading