// SPDX-License-Identifier: GPL-2.0-only /* * kernel/lockdep.c * * Runtime locking correctness validator * * Started by Ingo Molnar: * * Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra * * this code maps all the lock dependencies as they occur in a live kernel * and will warn about the following classes of locking bugs: * * - lock inversion scenarios * - circular lock dependencies * - hardirq/softirq safe/unsafe locking bugs * * Bugs are reported even if the current locking scenario does not cause * any deadlock at this point. * * I.e. if anytime in the past two locks were taken in a different order, * even if it happened for another task, even if those were different * locks (but of the same class as this lock), this code will detect it. * * Thanks to Arjan van de Ven for coming up with the initial idea of * mapping lock dependencies runtime.
*/ #define DISABLE_BRANCH_PROFILING #include <linux/mutex.h> #include <linux/sched.h> #include <linux/sched/clock.h> #include <linux/sched/task.h> #include <linux/sched/mm.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/spinlock.h> #include <linux/kallsyms.h> #include <linux/interrupt.h> #include <linux/stacktrace.h> #include <linux/debug_locks.h> #include <linux/irqflags.h> #include <linux/utsname.h> #include <linux/hash.h> #include <linux/ftrace.h> #include <linux/stringify.h> #include <linux/bitmap.h> #include <linux/bitops.h> #include <linux/gfp.h> #include <linux/random.h> #include <linux/jhash.h> #include <linux/nmi.h> #include <linux/rcupdate.h> #include <linux/kprobes.h> #include <linux/lockdep.h> #include <linux/context_tracking.h> #include <linux/console.h> #include <linux/kasan.h>
static __always_inline bool lockdep_enabled(void)
{ if (!debug_locks) returnfalse;
if (this_cpu_read(lockdep_recursion)) returnfalse;
if (current->lockdep_recursion) returnfalse;
returntrue;
}
/* * lockdep_lock: protects the lockdep graph, the hashes and the * class/list/hash allocators. * * This is one of the rare exceptions where it's justified * to use a raw spinlock - we really dont want the spinlock * code to recurse back into the lockdep code...
*/ static arch_spinlock_t __lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; staticstruct task_struct *__owner;
staticint graph_lock(void)
{
lockdep_lock();
lockevent_inc(lockdep_lock); /* * Make sure that if another CPU detected a bug while * walking the graph we dont change it (while the other * CPU is busy printing out stuff with the graph lock * dropped already)
*/ if (!debug_locks) {
lockdep_unlock(); return 0;
} return 1;
}
/* * Turn lock debugging off and return with 0 if it was off already, * and also release the graph lock:
*/ staticinlineint debug_locks_off_graph_unlock(void)
{ int ret = debug_locks_off();
/* * All data structures here are protected by the global debug_lock. * * nr_lock_classes is the number of elements of lock_classes[] that is * in use.
*/ #define KEYHASH_BITS (MAX_LOCKDEP_KEYS_BITS - 1) #define KEYHASH_SIZE (1UL << KEYHASH_BITS) staticstruct hlist_head lock_keys_hash[KEYHASH_SIZE]; unsignedlong nr_lock_classes; unsignedlong nr_zapped_classes; unsignedlong nr_dynamic_keys; unsignedlong max_lock_class_idx; struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS);
/* * We keep a global list of all lock classes. The list is only accessed with * the lockdep spinlock lock held. free_lock_classes is a list with free * elements. These elements are linked together by the lock_entry member in * struct lock_class.
*/ static LIST_HEAD(all_lock_classes); static LIST_HEAD(free_lock_classes);
/** * struct pending_free - information about data structures about to be freed * @zapped: Head of a list with struct lock_class elements. * @lock_chains_being_freed: Bitmap that indicates which lock_chains[] elements * are about to be freed.
*/ struct pending_free { struct list_head zapped;
DECLARE_BITMAP(lock_chains_being_freed, MAX_LOCKDEP_CHAINS);
};
/** * struct delayed_free - data structures used for delayed freeing * * A data structure for delayed freeing of data structures that may be * accessed by RCU readers at the time these were freed. * * @rcu_head: Used to schedule an RCU callback for freeing data structures. * @index: Index of @pf to which freed data structures are added. * @scheduled: Whether or not an RCU callback has been scheduled. * @pf: Array with information about data structures about to be freed.
*/ staticstruct delayed_free { struct rcu_head rcu_head; int index; int scheduled; struct pending_free pf[2];
} delayed_free;
/* * The lockdep classes are in a hash-table as well, for fast lookup:
*/ #define CLASSHASH_BITS (MAX_LOCKDEP_KEYS_BITS - 1) #define CLASSHASH_SIZE (1UL << CLASSHASH_BITS) #define __classhashfn(key) hash_long((unsignedlong)key, CLASSHASH_BITS) #define classhashentry(key) (classhash_table + __classhashfn((key)))
/* * We put the lock dependency chains into a hash-table as well, to cache * their existence:
*/ #define CHAINHASH_BITS (MAX_LOCKDEP_CHAINS_BITS-1) #define CHAINHASH_SIZE (1UL << CHAINHASH_BITS) #define __chainhashfn(chain) hash_long(chain, CHAINHASH_BITS) #define chainhashentry(chain) (chainhash_table + __chainhashfn((chain)))
/* * The hash key of the lock dependency chains is a hash itself too: * it's a hash of all locks taken up to that lock, including that lock. * It's a 64-bit hash, because it's important for the keys to be * unique.
*/ staticinline u64 iterate_chain_key(u64 key, u32 idx)
{
u32 k0 = key, k1 = key >> 32;
__jhash_mix(idx, k0, k1); /* Macro that modifies arguments! */
staticvoid print_lockdep_off(constchar *bug_msg)
{
printk(KERN_DEBUG "%s\n", bug_msg);
printk(KERN_DEBUG "turning off the locking correctness validator.\n"); #ifdef CONFIG_LOCK_STAT
printk(KERN_DEBUG "Please attach the output of /proc/lock_stat to the bug report\n"); #endif
}
unsignedlong nr_stack_trace_entries;
#ifdef CONFIG_PROVE_LOCKING /** * struct lock_trace - single stack backtrace * @hash_entry: Entry in a stack_trace_hash[] list. * @hash: jhash() of @entries. * @nr_entries: Number of entries in @entries. * @entries: Actual stack backtrace.
*/ struct lock_trace { struct hlist_node hash_entry;
u32 hash;
u32 nr_entries; unsignedlong entries[] __aligned(sizeof(unsignedlong));
}; #define LOCK_TRACE_SIZE_IN_LONGS \
(sizeof(struct lock_trace) / sizeof(unsignedlong)) /* * Stack-trace: sequence of lock_trace structures. Protected by the graph_lock.
*/ staticunsignedlong stack_trace[MAX_STACK_TRACE_ENTRIES]; staticstruct hlist_head stack_trace_hash[STACK_TRACE_HASH_SIZE];
staticchar get_usage_char(struct lock_class *class, enum lock_usage_bit bit)
{ /* * The usage character defaults to '.' (i.e., irqs disabled and not in * irq context), which is the safest usage category.
*/ char c = '.';
/* * The order of the following usage checks matters, which will * result in the outcome character as follows: * * - '+': irq is enabled and not in irq context * - '-': in irq context and irq is disabled * - '?': in irq context and irq is enabled
*/ if (class->usage_mask & lock_flag(bit + LOCK_USAGE_DIR_MASK)) {
c = '+'; if (class->usage_mask & lock_flag(bit))
c = '?';
} elseif (class->usage_mask & lock_flag(bit))
c = '-';
return c;
}
void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
{ int i = 0;
name = lock->name; if (!name)
name = __get_key_name(lock->key->subkeys, str);
printk(KERN_CONT "%s", name);
}
staticvoid print_lock(struct held_lock *hlock)
{ /* * We can be called locklessly through debug_show_all_locks() so be * extra careful, the hlock might have been released and cleared. * * If this indeed happens, lets pretend it does not hurt to continue * to print the lock unless the hlock class_idx does not point to a * registered class. The rationale here is: since we don't attempt * to distinguish whether we are in this situation, if it just * happened we can't count on class_idx to tell either.
*/ struct lock_class *lock = hlock_class(hlock);
staticvoid lockdep_print_held_locks(struct task_struct *p)
{ int i, depth = READ_ONCE(p->lockdep_depth);
if (!depth)
printk("no locks held by %s/%d.\n", p->comm, task_pid_nr(p)); else
printk("%d lock%s held by %s/%d:\n", depth,
str_plural(depth), p->comm, task_pid_nr(p)); /* * It's not reliable to print a task's held locks if it's not sleeping * and it's not the current task.
*/ if (p != current && task_is_running(p)) return; for (i = 0; i < depth; i++) {
printk(" #%d: ", i);
print_lock(p->held_locks + i);
}
}
/* * Is this the address of a static object:
*/ #ifdef __KERNEL__ staticint static_obj(constvoid *obj)
{ unsignedlong addr = (unsignedlong) obj;
if (is_kernel_core_data(addr)) return 1;
/* * keys are allowed in the __ro_after_init section.
*/ if (is_kernel_rodata(addr)) return 1;
/* * in initdata section and used during bootup only? * NOTE: On some platforms the initdata section is * outside of the _stext ... _end range.
*/ if (system_state < SYSTEM_FREEING_INITMEM &&
init_section_contains((void *)addr, 1)) return 1;
/* * in-kernel percpu var?
*/ if (is_kernel_percpu_address(addr)) return 1;
/* * To make lock name printouts unique, we calculate a unique * class->name_version generation counter. The caller must hold the graph * lock.
*/ staticint count_matching_names(struct lock_class *new_class)
{ struct lock_class *class; int count = 0;
/* used from NMI context -- must be lockless */ static noinstr struct lock_class *
look_up_lock_class(conststruct lockdep_map *lock, unsignedint subclass)
{ struct lockdep_subclass_key *key; struct hlist_head *hash_head; struct lock_class *class;
if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) {
instrumentation_begin();
debug_locks_off();
nbcon_cpu_emergency_enter();
printk(KERN_ERR "BUG: looking up invalid subclass: %u\n", subclass);
printk(KERN_ERR "turning off the locking correctness validator.\n");
dump_stack();
nbcon_cpu_emergency_exit();
instrumentation_end(); return NULL;
}
/* * If it is not initialised then it has never been locked, * so it won't be present in the hash table.
*/ if (unlikely(!lock->key)) return NULL;
/* * NOTE: the class-key must be unique. For dynamic locks, a static * lock_class_key variable is passed in through the mutex_init() * (or spin_lock_init()) call - which acts as the key. For static * locks we use the lock object itself as the key.
*/
BUILD_BUG_ON(sizeof(struct lock_class_key) > sizeof(struct lockdep_map));
key = lock->key->subkeys + subclass;
hash_head = classhashentry(key);
/* * We do an RCU walk of the hash, see lockdep_free_key_range().
*/ if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) return NULL;
hlist_for_each_entry_rcu_notrace(class, hash_head, hash_entry) { if (class->key == key) { /* * Huh! same key, different name? Did someone trample * on some memory? We're most confused.
*/
WARN_ONCE(class->name != lock->name &&
lock->key != &__lockdep_no_validate__, "Looking for class \"%s\" with key %ps, but found a different class \"%s\" with the same key\n",
lock->name, lock->key, class->name); returnclass;
}
}
return NULL;
}
/* * Static locks do not have their class-keys yet - for them the key is * the lock object itself. If the lock is in the per cpu area, the * canonical address of the lock (per cpu offset removed) is used.
*/ staticbool assign_lock_key(struct lockdep_map *lock)
{ unsignedlong can_addr, addr = (unsignedlong)lock;
#ifdef __KERNEL__ /* * lockdep_free_key_range() assumes that struct lock_class_key * objects do not overlap. Since we use the address of lock * objects as class key for static objects, check whether the * size of lock_class_key objects does not exceed the size of * the smallest lock object.
*/
BUILD_BUG_ON(sizeof(struct lock_class_key) > sizeof(raw_spinlock_t)); #endif
if (__is_kernel_percpu_address(addr, &can_addr))
lock->key = (void *)can_addr; elseif (__is_module_percpu_address(addr, &can_addr))
lock->key = (void *)can_addr; elseif (static_obj(lock))
lock->key = (void *)lock; else { /* Debug-check: all keys must be persistent! */
debug_locks_off();
nbcon_cpu_emergency_enter();
pr_err("INFO: trying to register non-static key.\n");
pr_err("The code is fine but needs lockdep annotation, or maybe\n");
pr_err("you didn't initialize this object before use?\n");
pr_err("turning off the locking correctness validator.\n");
dump_stack();
nbcon_cpu_emergency_exit(); returnfalse;
}
returntrue;
}
#ifdef CONFIG_DEBUG_LOCKDEP
/* Check whether element @e occurs in list @h */ staticbool in_list(struct list_head *e, struct list_head *h)
{ struct list_head *f;
list_for_each(f, h) { if (e == f) returntrue;
}
returnfalse;
}
/* * Check whether entry @e occurs in any of the locks_after or locks_before * lists.
*/ staticbool in_any_class_list(struct list_head *e)
{ struct lock_class *class; int i;
for (i = 0; i < ARRAY_SIZE(lock_classes); i++) { class = &lock_classes[i]; if (in_list(e, &class->locks_after) ||
in_list(e, &class->locks_before)) returntrue;
} returnfalse;
}
for (i = chain->base; i < chain->base + chain->depth; i++)
chain_key = iterate_chain_key(chain_key, chain_hlocks[i]); /* * The 'unsigned long long' casts avoid that a compiler warning * is reported when building tools/lib/lockdep.
*/ if (chain->chain_key != chain_key) {
printk(KERN_INFO "chain %lld: key %#llx <> %#llx\n",
(unsignedlonglong)(chain - lock_chains),
(unsignedlonglong)chain->chain_key,
(unsignedlonglong)chain_key); returnfalse;
} #endif returntrue;
}
staticbool in_any_zapped_class_list(struct lock_class *class)
{ struct pending_free *pf; int i;
for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf); i++, pf++) { if (in_list(&class->lock_entry, &pf->zapped)) returntrue;
}
/* Check whether all classes occur in a lock list. */ for (i = 0; i < ARRAY_SIZE(lock_classes); i++) { class = &lock_classes[i]; if (!in_list(&class->lock_entry, &all_lock_classes) &&
!in_list(&class->lock_entry, &free_lock_classes) &&
!in_any_zapped_class_list(class)) {
printk(KERN_INFO "class %px/%s is not in any class list\n", class, class->name ? : "(?)"); returnfalse;
}
}
/* Check whether all classes have valid lock lists. */ for (i = 0; i < ARRAY_SIZE(lock_classes); i++) { class = &lock_classes[i]; if (!class_lock_list_valid(class, &class->locks_before)) returnfalse; if (!class_lock_list_valid(class, &class->locks_after)) returnfalse;
}
/* Check the chain_key of all lock chains. */ for (i = 0; i < ARRAY_SIZE(chainhash_table); i++) {
head = chainhash_table + i;
hlist_for_each_entry_rcu(chain, head, entry) { if (!check_lock_chain_key(chain)) returnfalse;
}
}
/* * Check whether all list entries that are in use occur in a class * lock list.
*/
for_each_set_bit(i, list_entries_in_use, ARRAY_SIZE(list_entries)) {
e = list_entries + i; if (!in_any_class_list(&e->entry)) {
printk(KERN_INFO "list entry %d is not in any class list; class %s <> %s\n",
(unsignedint)(e - list_entries),
e->class->name ? : "(?)",
e->links_to->name ? : "(?)"); returnfalse;
}
}
/* * Check whether all list entries that are not in use do not occur in * a class lock list.
*/
for_each_clear_bit(i, list_entries_in_use, ARRAY_SIZE(list_entries)) {
e = list_entries + i; if (in_any_class_list(&e->entry)) {
printk(KERN_INFO "list entry %d occurs in a class list; class %s <> %s\n",
(unsignedint)(e - list_entries),
e->class && e->class->name ? e->class->name : "(?)",
e->links_to && e->links_to->name ?
e->links_to->name : "(?)"); returnfalse;
}
}
returntrue;
}
int check_consistency = 0;
module_param(check_consistency, int, 0644);
staticvoid check_data_structures(void)
{ staticbool once = false;
if (check_consistency && !once) { if (!__check_data_structures()) {
once = true;
WARN_ON(once);
}
}
}
#else/* CONFIG_DEBUG_LOCKDEP */
staticinlinevoid check_data_structures(void) { }
#endif/* CONFIG_DEBUG_LOCKDEP */
staticvoid init_chain_block_buckets(void);
/* * Initialize the lock_classes[] array elements, the free_lock_classes list * and also the delayed_free structure.
*/ staticvoid init_data_structures_once(void)
{ staticbool __read_mostly ds_initialized, rcu_head_initialized; int i;
if (likely(rcu_head_initialized)) return;
if (system_state >= SYSTEM_SCHEDULING) {
init_rcu_head(&delayed_free.rcu_head);
rcu_head_initialized = true;
}
/* Check whether a key has been registered as a dynamic key. */ staticbool is_dynamic_key(conststruct lock_class_key *key)
{ struct hlist_head *hash_head; struct lock_class_key *k; bool found = false;
if (WARN_ON_ONCE(static_obj(key))) returnfalse;
/* * If lock debugging is disabled lock_keys_hash[] may contain * pointers to memory that has already been freed. Avoid triggering * a use-after-free in that case by returning early.
*/ if (!debug_locks) returntrue;
hash_head = keyhashentry(key);
rcu_read_lock();
hlist_for_each_entry_rcu(k, hash_head, hash_entry) { if (k == key) {
found = true; break;
}
}
rcu_read_unlock();
return found;
}
/* * Register a lock's class in the hash-table, if the class is not present * yet. Otherwise we look it up. We cache the result in the lock object * itself, so actual lookup of the hash should be once per lock object.
*/ staticstruct lock_class *
register_lock_class(struct lockdep_map *lock, unsignedint subclass, int force)
{ struct lockdep_subclass_key *key; struct hlist_head *hash_head; struct lock_class *class; int idx;
DEBUG_LOCKS_WARN_ON(!irqs_disabled());
class = look_up_lock_class(lock, subclass); if (likely(class)) goto out_set_class_cache;
if (!lock->key) { if (!assign_lock_key(lock)) return NULL;
} elseif (!static_obj(lock->key) && !is_dynamic_key(lock->key)) { return NULL;
}
if (!graph_lock()) { return NULL;
} /* * We have to do the hash-walk again, to avoid races * with another CPU:
*/
hlist_for_each_entry_rcu(class, hash_head, hash_entry) { if (class->key == key) goto out_unlock_set;
}
init_data_structures_once();
/* Allocate a new lock class and add it to the hash. */ class = list_first_entry_or_null(&free_lock_classes, typeof(*class),
lock_entry); if (!class) { if (!debug_locks_off_graph_unlock()) { return NULL;
}
nbcon_cpu_emergency_enter();
print_lockdep_off("BUG: MAX_LOCKDEP_KEYS too low!");
dump_stack();
nbcon_cpu_emergency_exit(); return NULL;
}
nr_lock_classes++;
__set_bit(class - lock_classes, lock_classes_in_use);
debug_atomic_inc(nr_unused_locks);
class->key = key;
class->name = lock->name;
class->subclass = subclass;
WARN_ON_ONCE(!list_empty(&class->locks_before));
WARN_ON_ONCE(!list_empty(&class->locks_after));
class->name_version = count_matching_names(class);
class->wait_type_inner = lock->wait_type_inner;
class->wait_type_outer = lock->wait_type_outer;
class->lock_type = lock->lock_type; /* * We use RCU's safe list-add method to make * parallel walking of the hash-list safe:
*/
hlist_add_head_rcu(&class->hash_entry, hash_head); /* * Remove the class from the free list and add it to the global list * of classes.
*/
list_move_tail(&class->lock_entry, &all_lock_classes);
idx = class - lock_classes; if (idx > max_lock_class_idx)
max_lock_class_idx = idx;
if (verbose(class)) {
graph_unlock();
nbcon_cpu_emergency_enter();
printk("\nnew class %px: %s", class->key, class->name); if (class->name_version > 1)
printk(KERN_CONT "#%d", class->name_version);
printk(KERN_CONT "\n");
dump_stack();
nbcon_cpu_emergency_exit();
if (!graph_lock()) { return NULL;
}
}
out_unlock_set:
graph_unlock();
/* * Hash collision, did we smoke some? We found a class with a matching * hash but the subclass -- which is hashed in -- didn't match.
*/ if (DEBUG_LOCKS_WARN_ON(class->subclass != subclass)) return NULL;
returnclass;
}
#ifdef CONFIG_PROVE_LOCKING /* * Allocate a lockdep entry. (assumes the graph_lock held, returns * with NULL on failure)
*/ staticstruct lock_list *alloc_list_entry(void)
{ int idx = find_first_zero_bit(list_entries_in_use,
ARRAY_SIZE(list_entries));
if (idx >= ARRAY_SIZE(list_entries)) { if (!debug_locks_off_graph_unlock()) return NULL;
/* * Add a new dependency to the head of the list:
*/ staticint add_lock_to_list(struct lock_class *this, struct lock_class *links_to, struct list_head *head,
u16 distance, u8 dep, conststruct lock_trace *trace)
{ struct lock_list *entry; /* * Lock not present yet - get a new dependency struct and * add it to the list:
*/
entry = alloc_list_entry(); if (!entry) return 0;
entry->class = this;
entry->links_to = links_to;
entry->dep = dep;
entry->distance = distance;
entry->trace = trace; /* * Both allocation and removal are done under the graph lock; but * iteration is under RCU-sched; see look_up_lock_class() and * lockdep_free_key_range().
*/
list_add_tail_rcu(&entry->entry, head);
return 1;
}
/* * For good efficiency of modular, we use power of 2
*/ #define MAX_CIRCULAR_QUEUE_SIZE (1UL << CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS) #define CQ_MASK (MAX_CIRCULAR_QUEUE_SIZE-1)
/* * The circular_queue and helpers are used to implement graph * breadth-first search (BFS) algorithm, by which we can determine * whether there is a path from a lock to another. In deadlock checks, * a path from the next lock to be acquired to a previous held lock * indicates that adding the <prev> -> <next> lock dependency will * produce a circle in the graph. Breadth-first search instead of * depth-first search is used in order to find the shortest (circular) * path.
*/ struct circular_queue { struct lock_list *element[MAX_CIRCULAR_QUEUE_SIZE]; unsignedint front, rear;
};
/* * Dequeue an element from the circular_queue, return a lock_list if * the queue is not empty, or NULL if otherwise.
*/ staticinlinestruct lock_list * __cq_dequeue(struct circular_queue *cq)
{ struct lock_list * lock;
/* * Return the forward or backward dependency list. * * @lock: the lock_list to get its class's dependency list * @offset: the offset to struct lock_class to determine whether it is * locks_after or locks_before
*/ staticinlinestruct list_head *get_dep_list(struct lock_list *lock, int offset)
{ void *lock_class = lock->class;
return lock_class + offset;
} /* * Return values of a bfs search: * * BFS_E* indicates an error * BFS_R* indicates a result (match or not) * * BFS_EINVALIDNODE: Find a invalid node in the graph. * * BFS_EQUEUEFULL: The queue is full while doing the bfs. * * BFS_RMATCH: Find the matched node in the graph, and put that node into * *@target_entry. * * BFS_RNOMATCH: Haven't found the matched node and keep *@target_entry * _unchanged_.
*/ enum bfs_result {
BFS_EINVALIDNODE = -2,
BFS_EQUEUEFULL = -1,
BFS_RMATCH = 0,
BFS_RNOMATCH = 1,
};
/* * bfs_result < 0 means error
*/ staticinlinebool bfs_error(enum bfs_result res)
{ return res < 0;
}
/* * DEP_*_BIT in lock_list::dep * * For dependency @prev -> @next: * * SR: @prev is shared reader (->read != 0) and @next is recursive reader * (->read == 2) * ER: @prev is exclusive locker (->read == 0) and @next is recursive reader * SN: @prev is shared reader and @next is non-recursive locker (->read != 2) * EN: @prev is exclusive locker and @next is non-recursive locker * * Note that we define the value of DEP_*_BITs so that: * bit0 is prev->read == 0 * bit1 is next->read != 2
*/ #define DEP_SR_BIT (0 + (0 << 1)) /* 0 */ #define DEP_ER_BIT (1 + (0 << 1)) /* 1 */ #define DEP_SN_BIT (0 + (1 << 1)) /* 2 */ #define DEP_EN_BIT (1 + (1 << 1)) /* 3 */
/* * Initialize a lock_list entry @lock belonging to @class as the root for a BFS * search.
*/ staticinlinevoid __bfs_init_root(struct lock_list *lock, struct lock_class *class)
{
lock->class = class;
lock->parent = NULL;
lock->only_xr = 0;
}
/* * Initialize a lock_list entry @lock based on a lock acquisition @hlock as the * root for a BFS search. * * ->only_xr of the initial lock node is set to @hlock->read == 2, to make sure * that <prev> -> @hlock and @hlock -> <whatever __bfs() found> is not -(*R)-> * and -(S*)->.
*/ staticinlinevoid bfs_init_root(struct lock_list *lock, struct held_lock *hlock)
{
__bfs_init_root(lock, hlock_class(hlock));
lock->only_xr = (hlock->read == 2);
}
/* * Similar to bfs_init_root() but initialize the root for backwards BFS. * * ->only_xr of the initial lock node is set to @hlock->read != 0, to make sure * that <next> -> @hlock and @hlock -> <whatever backwards BFS found> is not * -(*S)-> and -(R*)-> (reverse order of -(*R)-> and -(S*)->).
*/ staticinlinevoid bfs_init_rootb(struct lock_list *lock, struct held_lock *hlock)
{
__bfs_init_root(lock, hlock_class(hlock));
lock->only_xr = (hlock->read != 0);
}
staticinlinestruct lock_list *__bfs_next(struct lock_list *lock, int offset)
{ if (!lock || !lock->parent) return NULL;
/* * Breadth-First Search to find a strong path in the dependency graph. * * @source_entry: the source of the path we are searching for. * @data: data used for the second parameter of @match function * @match: match function for the search * @target_entry: pointer to the target of a matched path * @offset: the offset to struct lock_class to determine whether it is * locks_after or locks_before * * We may have multiple edges (considering different kinds of dependencies, * e.g. ER and SN) between two nodes in the dependency graph. But * only the strong dependency path in the graph is relevant to deadlocks. A * strong dependency path is a dependency path that doesn't have two adjacent * dependencies as -(*R)-> -(S*)->, please see: * * Documentation/locking/lockdep-design.rst * * for more explanation of the definition of strong dependency paths * * In __bfs(), we only traverse in the strong dependency path: * * In lock_list::only_xr, we record whether the previous dependency only * has -(*R)-> in the search, and if it does (prev only has -(*R)->), we * filter out any -(S*)-> in the current dependency and after that, the * ->only_xr is set according to whether we only have -(*R)-> left.
*/ staticenum bfs_result __bfs(struct lock_list *source_entry, void *data, bool (*match)(struct lock_list *entry, void *data), bool (*skip)(struct lock_list *entry, void *data), struct lock_list **target_entry, int offset)
{ struct circular_queue *cq = &lock_cq; struct lock_list *lock = NULL; struct lock_list *entry; struct list_head *head; unsignedint cq_depth; bool first;
lockdep_assert_locked();
__cq_init(cq);
__cq_enqueue(cq, source_entry);
while ((lock = __bfs_next(lock, offset)) || (lock = __cq_dequeue(cq))) { if (!lock->class) return BFS_EINVALIDNODE;
/* * Step 1: check whether we already finish on this one. * * If we have visited all the dependencies from this @lock to * others (iow, if we have visited all lock_list entries in * @lock->class->locks_{after,before}) we skip, otherwise go * and visit all the dependencies in the list and mark this * list accessed.
*/ if (lock_accessed(lock)) continue; else
mark_lock_accessed(lock);
/* * Step 2: check whether prev dependency and this form a strong * dependency path.
*/ if (lock->parent) { /* Parent exists, check prev dependency */
u8 dep = lock->dep; bool prev_only_xr = lock->parent->only_xr;
/* * Mask out all -(S*)-> if we only have *R in previous * step, because -(*R)-> -(S*)-> don't make up a strong * dependency.
*/ if (prev_only_xr)
dep &= ~(DEP_SR_MASK | DEP_SN_MASK);
/* If nothing left, we skip */ if (!dep) continue;
/* If there are only -(*R)-> left, set that for the next step */
lock->only_xr = !(dep & (DEP_SN_MASK | DEP_EN_MASK));
}
/* * Step 3: we haven't visited this and there is a strong * dependency path to this, so check with @match. * If @skip is provide and returns true, we skip this * lock (and any path this lock is in).
*/ if (skip && skip(lock, data)) continue;
if (match(lock, data)) {
*target_entry = lock; return BFS_RMATCH;
}
/* * Step 4: if not match, expand the path by adding the * forward or backwards dependencies in the search *
*/
first = true;
head = get_dep_list(lock, offset);
list_for_each_entry_rcu(entry, head, entry) {
visit_lock_entry(entry, lock);
/* * Note we only enqueue the first of the list into the * queue, because we can always find a sibling * dependency from one (see __bfs_next()), as a result * the space of queue is saved.
*/ if (!first) continue;
first = false;
if (__cq_enqueue(cq, entry)) return BFS_EQUEUEFULL;
/* * Print a dependency chain entry (this is only done when a deadlock * has been detected):
*/ static noinline void
print_circular_bug_entry(struct lock_list *target, int depth)
{ if (debug_locks_silent) return;
printk("\n-> #%u", depth);
print_lock_name(NULL, target->class);
printk(KERN_CONT ":\n");
print_lock_trace(target->trace, 6);
}
/* * A direct locking problem where unsafe_class lock is taken * directly by safe_class lock, then all we need to show * is the deadlock scenario, as it is obvious that the * unsafe lock is taken under the safe lock. * * But if there is a chain instead, where the safe lock takes * an intermediate lock (middle_class) where this lock is * not the same as the safe lock, then the lock chain is * used to describe the problem. Otherwise we would need * to show a different CPU case for each link in the chain * from the safe_class lock to the unsafe_class lock.
*/ if (parent != source) {
printk("Chain exists of:\n ");
__print_lock_name(src, source);
printk(KERN_CONT " --> ");
__print_lock_name(NULL, parent);
printk(KERN_CONT " --> ");
__print_lock_name(tgt, target);
printk(KERN_CONT "\n\n");
}
/* * When a circular dependency is detected, print the * header first:
*/ static noinline void
print_circular_bug_header(struct lock_list *entry, unsignedint depth, struct held_lock *check_src, struct held_lock *check_tgt)
{ struct task_struct *curr = current;
if (debug_locks_silent) return;
pr_warn("\n");
pr_warn("======================================================\n");
pr_warn("WARNING: possible circular locking dependency detected\n");
print_kernel_ident();
pr_warn("------------------------------------------------------\n");
pr_warn("%s/%d is trying to acquire lock:\n",
curr->comm, task_pid_nr(curr));
print_lock(check_src);
pr_warn("\nbut task is already holding lock:\n");
print_lock(check_tgt);
pr_warn("\nwhich lock already depends on the new lock.\n\n");
pr_warn("\nthe existing dependency chain (in reverse order) is:\n");
print_circular_bug_entry(entry, depth);
}
/* * We are about to add B -> A into the dependency graph, and in __bfs() a * strong dependency path A -> .. -> B is found: hlock_class equals * entry->class. * * We will have a deadlock case (conflict) if A -> .. -> B -> A is a strong * dependency cycle, that means: * * Either * * a) B -> A is -(E*)-> * * or * * b) A -> .. -> B is -(*N)-> (i.e. A -> .. -(*N)-> B) * * as then we don't have -(*R)-> -(S*)-> in the cycle.
*/ staticinlinebool hlock_conflict(struct lock_list *entry, void *data)
{ struct held_lock *hlock = (struct held_lock *)data;
return hlock_class(hlock) == entry->class && /* Found A -> .. -> B */
(hlock->read == 0 || /* B -> A is -(E*)-> */
!entry->only_xr); /* A -> .. -> B is -(*N)-> */
}
/* * Prove that the dependency graph starting at <src> can not * lead to <target>. If it can, there is a circle when adding * <target> -> <src> dependency. * * Print an error and return BFS_RMATCH if it does.
*/ static noinline enum bfs_result
check_noncircular(struct held_lock *src, struct held_lock *target, struct lock_trace **const trace)
{ enum bfs_result ret; struct lock_list *target_entry; struct lock_list src_entry;
bfs_init_root(&src_entry, src);
debug_atomic_inc(nr_cyclic_checks);
ret = check_path(target, &src_entry, hlock_conflict, NULL, &target_entry);
if (unlikely(ret == BFS_RMATCH)) { if (!*trace) { /* * If save_trace fails here, the printing might * trigger a WARN but because of the !nr_entries it * should not do bad things.
*/
*trace = save_trace();
}
/* * Forwards and backwards subgraph searching, for the purposes of * proving that two subgraphs can be connected by a new dependency * without creating any illegal irq-safe -> irq-unsafe lock dependency. * * A irq safe->unsafe deadlock happens with the following conditions: * * 1) We have a strong dependency path A -> ... -> B * * 2) and we have ENABLED_IRQ usage of B and USED_IN_IRQ usage of A, therefore * irq can create a new dependency B -> A (consider the case that a holder * of B gets interrupted by an irq whose handler will try to acquire A). * * 3) the dependency circle A -> ... -> B -> A we get from 1) and 2) is a * strong circle: * * For the usage bits of B: * a) if A -> B is -(*N)->, then B -> A could be any type, so any * ENABLED_IRQ usage suffices. * b) if A -> B is -(*R)->, then B -> A must be -(E*)->, so only * ENABLED_IRQ_*_READ usage suffices. * * For the usage bits of A: * c) if A -> B is -(E*)->, then B -> A could be any type, so any * USED_IN_IRQ usage suffices. * d) if A -> B is -(S*)->, then B -> A must be -(*N)->, so only * USED_IN_IRQ_*_READ usage suffices.
*/
/* * There is a strong dependency path in the dependency graph: A -> B, and now * we need to decide which usage bit of A should be accumulated to detect * safe->unsafe bugs. * * Note that usage_accumulate() is used in backwards search, so ->only_xr * stands for whether A -> B only has -(S*)-> (in this case ->only_xr is true). * * As above, if only_xr is false, which means A -> B has -(E*)-> dependency * path, any usage of A should be considered. Otherwise, we should only * consider _READ usage.
*/ staticinlinebool usage_accumulate(struct lock_list *entry, void *mask)
{ if (!entry->only_xr)
*(unsignedlong *)mask |= entry->class->usage_mask; else/* Mask out _READ usage bits */
*(unsignedlong *)mask |= (entry->class->usage_mask & LOCKF_IRQ);
returnfalse;
}
/* * There is a strong dependency path in the dependency graph: A -> B, and now * we need to decide which usage bit of B conflicts with the usage bits of A, * i.e. which usage bit of B may introduce safe->unsafe deadlocks. * * As above, if only_xr is false, which means A -> B has -(*N)-> dependency * path, any usage of B should be considered. Otherwise, we should only * consider _READ usage.
*/ staticinlinebool usage_match(struct lock_list *entry, void *mask)
{ if (!entry->only_xr) return !!(entry->class->usage_mask & *(unsignedlong *)mask); else/* Mask out _READ usage bits */ return !!((entry->class->usage_mask & LOCKF_IRQ) & *(unsignedlong *)mask);
}
/* * Skip local_lock() for irq inversion detection. * * For !RT, local_lock() is not a real lock, so it won't carry any * dependency. * * For RT, an irq inversion happens when we have lock A and B, and on * some CPU we can have: * * lock(A); * <interrupted> * lock(B); * * where lock(B) cannot sleep, and we have a dependency B -> ... -> A. * * Now we prove local_lock() cannot exist in that dependency. First we * have the observation for any lock chain L1 -> ... -> Ln, for any * 1 <= i <= n, Li.inner_wait_type <= L1.inner_wait_type, otherwise * wait context check will complain. And since B is not a sleep lock, * therefore B.inner_wait_type >= 2, and since the inner_wait_type of * local_lock() is 3, which is greater than 2, therefore there is no * way the local_lock() exists in the dependency B -> ... -> A. * * As a result, we will skip local_lock(), when we search for irq * inversion bugs.
*/ if (entry->class->lock_type == LD_LOCK_PERCPU &&
DEBUG_LOCKS_WARN_ON(entry->class->wait_type_inner < LD_WAIT_CONFIG)) returnfalse;
/* * Skip WAIT_OVERRIDE for irq inversion detection -- it's not actually * a lock and only used to override the wait_type.
*/
returntrue;
}
/* * Find a node in the forwards-direction dependency sub-graph starting * at @root->class that matches @bit. * * Return BFS_MATCH if such a node exists in the subgraph, and put that node * into *@target_entry.
*/ staticenum bfs_result
find_usage_forwards(struct lock_list *root, unsignedlong usage_mask, struct lock_list **target_entry)
{ enum bfs_result result;
debug_atomic_inc(nr_find_usage_forwards_checks);
result = __bfs_forwards(root, &usage_mask, usage_match, usage_skip, target_entry);
return result;
}
/* * Find a node in the backwards-direction dependency sub-graph starting * at @root->class that matches @bit.
*/ staticenum bfs_result
find_usage_backwards(struct lock_list *root, unsignedlong usage_mask, struct lock_list **target_entry)
{ enum bfs_result result;
debug_atomic_inc(nr_find_usage_backwards_checks);
result = __bfs_backwards(root, &usage_mask, usage_match, usage_skip, target_entry);
return result;
}
staticvoid print_lock_class_header(struct lock_class *class, int depth)
{ int bit;
/* * Dependency path printing: * * After BFS we get a lock dependency path (linked via ->parent of lock_list), * printing out each lock in the dependency path will help on understanding how * the deadlock could happen. Here are some details about dependency path * printing: * * 1) A lock_list can be either forwards or backwards for a lock dependency, * for a lock dependency A -> B, there are two lock_lists: * * a) lock_list in the ->locks_after list of A, whose ->class is B and * ->links_to is A. In this case, we can say the lock_list is * "A -> B" (forwards case). * * b) lock_list in the ->locks_before list of B, whose ->class is A * and ->links_to is B. In this case, we can say the lock_list is * "B <- A" (bacwards case). * * The ->trace of both a) and b) point to the call trace where B was * acquired with A held. * * 2) A "helper" lock_list is introduced during BFS, this lock_list doesn't * represent a certain lock dependency, it only provides an initial entry * for BFS. For example, BFS may introduce a "helper" lock_list whose * ->class is A, as a result BFS will search all dependencies starting with * A, e.g. A -> B or A -> C. * * The notation of a forwards helper lock_list is like "-> A", which means * we should search the forwards dependencies starting with "A", e.g A -> B * or A -> C. * * The notation of a bacwards helper lock_list is like "<- B", which means * we should search the backwards dependencies ending with "B", e.g. * B <- A or B <- C.
*/
/* * printk the shortest lock dependencies from @root to @leaf in reverse order. * * We have a lock dependency path as follow: * * @root @leaf * | | * V V * ->parent ->parent * | lock_list | <--------- | lock_list | ... | lock_list | <--------- | lock_list | * | -> L1 | | L1 -> L2 | ... |Ln-2 -> Ln-1| | Ln-1 -> Ln| * * , so it's natural that we start from @leaf and print every ->class and * ->trace until we reach the @root.
*/ staticvoid __used
print_shortest_lock_dependencies(struct lock_list *leaf, struct lock_list *root)
{ struct lock_list *entry = leaf; int depth;
/*compute depth from generated tree by BFS*/
depth = get_lock_depth(leaf);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.