[PATCH] lockdep: register_lock_class() fix
[sfrench/cifs-2.6.git] / kernel / lockdep.c
index f76a24f2ac20b88a1fe83135b99855e1d536f015..62e73ce681972ad350cda5b50037ab30c381c67a 100644 (file)
@@ -140,13 +140,6 @@ void lockdep_on(void)
 
 EXPORT_SYMBOL(lockdep_on);
 
-int lockdep_internal(void)
-{
-       return current->lockdep_recursion != 0;
-}
-
-EXPORT_SYMBOL(lockdep_internal);
-
 /*
  * Debugging switches:
  */
@@ -359,7 +352,7 @@ get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4
 
 static void print_lock_name(struct lock_class *class)
 {
-       char str[128], c1, c2, c3, c4;
+       char str[KSYM_NAME_LEN + 1], c1, c2, c3, c4;
        const char *name;
 
        get_usage_chars(class, &c1, &c2, &c3, &c4);
@@ -381,7 +374,7 @@ static void print_lock_name(struct lock_class *class)
 static void print_lockdep_cache(struct lockdep_map *lock)
 {
        const char *name;
-       char str[128];
+       char str[KSYM_NAME_LEN + 1];
 
        name = lock->name;
        if (!name)
@@ -451,7 +444,9 @@ static void print_lock_dependencies(struct lock_class *class, int depth)
        print_lock_class_header(class, depth);
 
        list_for_each_entry(entry, &class->locks_after, entry) {
-               DEBUG_LOCKS_WARN_ON(!entry->class);
+               if (DEBUG_LOCKS_WARN_ON(!entry->class))
+                       return;
+
                print_lock_dependencies(entry->class, depth + 1);
 
                printk("%*s ... acquired at:\n",depth,"");
@@ -1187,6 +1182,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
        struct lockdep_subclass_key *key;
        struct list_head *hash_head;
        struct lock_class *class;
+       unsigned long flags;
 
        class = look_up_lock_class(lock, subclass);
        if (likely(class))
@@ -1208,6 +1204,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
        key = lock->key->subkeys + subclass;
        hash_head = classhashentry(key);
 
+       raw_local_irq_save(flags);
        __raw_spin_lock(&hash_lock);
        /*
         * We have to do the hash-walk again, to avoid races
@@ -1222,6 +1219,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
         */
        if (nr_lock_classes >= MAX_LOCKDEP_KEYS) {
                __raw_spin_unlock(&hash_lock);
+               raw_local_irq_restore(flags);
                debug_locks_off();
                printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
                printk("turning off the locking correctness validator.\n");
@@ -1244,15 +1242,18 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
 
        if (verbose(class)) {
                __raw_spin_unlock(&hash_lock);
+               raw_local_irq_restore(flags);
                printk("\nnew class %p: %s", class->key, class->name);
                if (class->name_version > 1)
                        printk("#%d", class->name_version);
                printk("\n");
                dump_stack();
+               raw_local_irq_save(flags);
                __raw_spin_lock(&hash_lock);
        }
 out_unlock_set:
        __raw_spin_unlock(&hash_lock);
+       raw_local_irq_restore(flags);
 
        if (!subclass || force)
                lock->class_cache = class;
@@ -1733,6 +1734,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
                debug_atomic_dec(&nr_unused_locks);
                break;
        default:
+               __raw_spin_unlock(&hash_lock);
                debug_locks_off();
                WARN_ON(1);
                return 0;