aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/locking/lockdep.c50
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
4204void 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 */
4209static 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
4226void 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();