diff options
| -rw-r--r-- | kernel/locking/lockdep.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index b5c8fcb6c070..81388d028ac7 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
| @@ -4201,13 +4201,33 @@ void lockdep_free_key_range(void *start, unsigned long size) | |||
| 4201 | */ | 4201 | */ |
| 4202 | } | 4202 | } |
| 4203 | 4203 | ||
| 4204 | void lockdep_reset_lock(struct lockdep_map *lock) | 4204 | /* |
| 4205 | * Check whether any element of the @lock->class_cache[] array refers to a | ||
| 4206 | * registered lock class. The caller must hold either the graph lock or the | ||
| 4207 | * RCU read lock. | ||
| 4208 | */ | ||
| 4209 | static bool lock_class_cache_is_registered(struct lockdep_map *lock) | ||
| 4205 | { | 4210 | { |
| 4206 | struct lock_class *class; | 4211 | struct lock_class *class; |
| 4207 | struct hlist_head *head; | 4212 | struct hlist_head *head; |
| 4208 | unsigned long flags; | ||
| 4209 | int i, j; | 4213 | int i, j; |
| 4210 | int locked; | 4214 | |
| 4215 | for (i = 0; i < CLASSHASH_SIZE; i++) { | ||
| 4216 | head = classhash_table + i; | ||
| 4217 | hlist_for_each_entry_rcu(class, head, hash_entry) { | ||
| 4218 | for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) | ||
| 4219 | if (lock->class_cache[j] == class) | ||
| 4220 | return true; | ||
| 4221 | } | ||
| 4222 | } | ||
| 4223 | return false; | ||
| 4224 | } | ||
| 4225 | |||
| 4226 | void lockdep_reset_lock(struct lockdep_map *lock) | ||
| 4227 | { | ||
| 4228 | struct lock_class *class; | ||
| 4229 | unsigned long flags; | ||
| 4230 | int j, locked; | ||
| 4211 | 4231 | ||
| 4212 | raw_local_irq_save(flags); | 4232 | raw_local_irq_save(flags); |
| 4213 | 4233 | ||
| @@ -4227,24 +4247,14 @@ void lockdep_reset_lock(struct lockdep_map *lock) | |||
| 4227 | * be gone. | 4247 | * be gone. |
| 4228 | */ | 4248 | */ |
| 4229 | locked = graph_lock(); | 4249 | locked = graph_lock(); |
| 4230 | for (i = 0; i < CLASSHASH_SIZE; i++) { | 4250 | if (unlikely(lock_class_cache_is_registered(lock))) { |
| 4231 | head = classhash_table + i; | 4251 | if (debug_locks_off_graph_unlock()) { |
| 4232 | hlist_for_each_entry_rcu(class, head, hash_entry) { | 4252 | /* |
| 4233 | int match = 0; | 4253 | * We all just reset everything, how did it match? |
| 4234 | 4254 | */ | |
| 4235 | for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) | 4255 | WARN_ON(1); |
| 4236 | match |= class == lock->class_cache[j]; | ||
| 4237 | |||
| 4238 | if (unlikely(match)) { | ||
| 4239 | if (debug_locks_off_graph_unlock()) { | ||
| 4240 | /* | ||
| 4241 | * We all just reset everything, how did it match? | ||
| 4242 | */ | ||
| 4243 | WARN_ON(1); | ||
| 4244 | } | ||
| 4245 | goto out_restore; | ||
| 4246 | } | ||
| 4247 | } | 4256 | } |
| 4257 | goto out_restore; | ||
| 4248 | } | 4258 | } |
| 4249 | if (locked) | 4259 | if (locked) |
| 4250 | graph_unlock(); | 4260 | graph_unlock(); |
