diff options
Diffstat (limited to 'kernel/locking')
| -rw-r--r-- | kernel/locking/lockdep.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 53ab2f85d77e..2324ba5310db 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
| @@ -2000,6 +2000,77 @@ static inline int get_first_held_lock(struct task_struct *curr, | |||
| 2000 | } | 2000 | } |
| 2001 | 2001 | ||
| 2002 | /* | 2002 | /* |
| 2003 | * Returns the next chain_key iteration | ||
| 2004 | */ | ||
| 2005 | static u64 print_chain_key_iteration(int class_idx, u64 chain_key) | ||
| 2006 | { | ||
| 2007 | u64 new_chain_key = iterate_chain_key(chain_key, class_idx); | ||
| 2008 | |||
| 2009 | printk(" class_idx:%d -> chain_key:%016Lx", | ||
| 2010 | class_idx, | ||
| 2011 | (unsigned long long)new_chain_key); | ||
| 2012 | return new_chain_key; | ||
| 2013 | } | ||
| 2014 | |||
| 2015 | static void | ||
| 2016 | print_chain_keys_held_locks(struct task_struct *curr, struct held_lock *hlock_next) | ||
| 2017 | { | ||
| 2018 | struct held_lock *hlock; | ||
| 2019 | u64 chain_key = 0; | ||
| 2020 | int depth = curr->lockdep_depth; | ||
| 2021 | int i; | ||
| 2022 | |||
| 2023 | printk("depth: %u\n", depth + 1); | ||
| 2024 | for (i = get_first_held_lock(curr, hlock_next); i < depth; i++) { | ||
| 2025 | hlock = curr->held_locks + i; | ||
| 2026 | chain_key = print_chain_key_iteration(hlock->class_idx, chain_key); | ||
| 2027 | |||
| 2028 | print_lock(hlock); | ||
| 2029 | } | ||
| 2030 | |||
| 2031 | print_chain_key_iteration(hlock_next->class_idx, chain_key); | ||
| 2032 | print_lock(hlock_next); | ||
| 2033 | } | ||
| 2034 | |||
| 2035 | static void print_chain_keys_chain(struct lock_chain *chain) | ||
| 2036 | { | ||
| 2037 | int i; | ||
| 2038 | u64 chain_key = 0; | ||
| 2039 | int class_id; | ||
| 2040 | |||
| 2041 | printk("depth: %u\n", chain->depth); | ||
| 2042 | for (i = 0; i < chain->depth; i++) { | ||
| 2043 | class_id = chain_hlocks[chain->base + i]; | ||
| 2044 | chain_key = print_chain_key_iteration(class_id + 1, chain_key); | ||
| 2045 | |||
| 2046 | print_lock_name(lock_classes + class_id); | ||
| 2047 | printk("\n"); | ||
| 2048 | } | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | static void print_collision(struct task_struct *curr, | ||
| 2052 | struct held_lock *hlock_next, | ||
| 2053 | struct lock_chain *chain) | ||
| 2054 | { | ||
| 2055 | printk("\n"); | ||
| 2056 | printk("======================\n"); | ||
| 2057 | printk("[chain_key collision ]\n"); | ||
| 2058 | print_kernel_ident(); | ||
| 2059 | printk("----------------------\n"); | ||
| 2060 | printk("%s/%d: ", current->comm, task_pid_nr(current)); | ||
| 2061 | printk("Hash chain already cached but the contents don't match!\n"); | ||
| 2062 | |||
| 2063 | printk("Held locks:"); | ||
| 2064 | print_chain_keys_held_locks(curr, hlock_next); | ||
| 2065 | |||
| 2066 | printk("Locks in cached chain:"); | ||
| 2067 | print_chain_keys_chain(chain); | ||
| 2068 | |||
| 2069 | printk("\nstack backtrace:\n"); | ||
| 2070 | dump_stack(); | ||
| 2071 | } | ||
| 2072 | |||
| 2073 | /* | ||
| 2003 | * Checks whether the chain and the current held locks are consistent | 2074 | * Checks whether the chain and the current held locks are consistent |
| 2004 | * in depth and also in content. If they are not it most likely means | 2075 | * in depth and also in content. If they are not it most likely means |
| 2005 | * that there was a collision during the calculation of the chain_key. | 2076 | * that there was a collision during the calculation of the chain_key. |
| @@ -2014,14 +2085,18 @@ static int check_no_collision(struct task_struct *curr, | |||
| 2014 | 2085 | ||
| 2015 | i = get_first_held_lock(curr, hlock); | 2086 | i = get_first_held_lock(curr, hlock); |
| 2016 | 2087 | ||
| 2017 | if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) | 2088 | if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) { |
| 2089 | print_collision(curr, hlock, chain); | ||
| 2018 | return 0; | 2090 | return 0; |
| 2091 | } | ||
| 2019 | 2092 | ||
| 2020 | for (j = 0; j < chain->depth - 1; j++, i++) { | 2093 | for (j = 0; j < chain->depth - 1; j++, i++) { |
| 2021 | id = curr->held_locks[i].class_idx - 1; | 2094 | id = curr->held_locks[i].class_idx - 1; |
| 2022 | 2095 | ||
| 2023 | if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) | 2096 | if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) { |
| 2097 | print_collision(curr, hlock, chain); | ||
| 2024 | return 0; | 2098 | return 0; |
| 2099 | } | ||
| 2025 | } | 2100 | } |
| 2026 | #endif | 2101 | #endif |
| 2027 | return 1; | 2102 | return 1; |
