Skip to content

Commit

Permalink
lockdep: Check if nested lock is actually held
Browse files Browse the repository at this point in the history
It is considered good form to lock the lock you claim to be nested in.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>

[ removed nest_lock arg to print_lock_nested_lock_not_held in favour
  of hlock->nest_lock, also renamed the lock arg to hlock since its
  a held_lock type ]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/5051A9E7.5040501@canonical.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Maarten Lankhorst authored and Ingo Molnar committed Sep 13, 2012
1 parent 0bd1189 commit d094595
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions kernel/lockdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -2998,6 +2998,42 @@ EXPORT_SYMBOL_GPL(lockdep_init_map);

struct lock_class_key __lockdep_no_validate__;

static int
print_lock_nested_lock_not_held(struct task_struct *curr,
struct held_lock *hlock,
unsigned long ip)
{
if (!debug_locks_off())
return 0;
if (debug_locks_silent)
return 0;

printk("\n");
printk("==================================\n");
printk("[ BUG: Nested lock was not taken ]\n");
print_kernel_ident();
printk("----------------------------------\n");

printk("%s/%d is trying to lock:\n", curr->comm, task_pid_nr(curr));
print_lock(hlock);

printk("\nbut this task is not holding:\n");
printk("%s\n", hlock->nest_lock->name);

printk("\nstack backtrace:\n");
dump_stack();

printk("\nother info that might help us debug this:\n");
lockdep_print_held_locks(curr);

printk("\nstack backtrace:\n");
dump_stack();

return 0;
}

static int __lock_is_held(struct lockdep_map *lock);

/*
* This gets called for every mutex_lock*()/spin_lock*() operation.
* We maintain the dependency maps and validate the locking attempt:
Expand Down Expand Up @@ -3139,6 +3175,9 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
}
chain_key = iterate_chain_key(chain_key, id);

if (nest_lock && !__lock_is_held(nest_lock))
return print_lock_nested_lock_not_held(curr, hlock, ip);

if (!validate_chain(curr, lock, hlock, chain_head, chain_key))
return 0;

Expand Down

0 comments on commit d094595

Please sign in to comment.