Skip to content

Commit

Permalink
[PATCH] debug: workqueue locking sanity
Browse files Browse the repository at this point in the history
Workqueue functions should not leak locks, assert so, printing the
last function ran.

Use macros in lockdep.h to avoid include dependency pains.

[akpm@osdl.org: build fix]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Peter Zijlstra authored and Linus Torvalds committed Dec 7, 2006
1 parent 6fb50ea commit d5abe66
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ extern void lock_release(struct lockdep_map *lock, int nested,

# define INIT_LOCKDEP .lockdep_recursion = 0,

#define lockdep_depth(tsk) ((tsk)->lockdep_depth)

#else /* !LOCKDEP */

static inline void lockdep_off(void)
Expand Down Expand Up @@ -277,6 +279,9 @@ static inline int lockdep_internal(void)
* The class key takes no space if lockdep is disabled:
*/
struct lock_class_key { };

#define lockdep_depth(tsk) (0)

#endif /* !LOCKDEP */

#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
Expand Down
13 changes: 13 additions & 0 deletions kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <linux/hardirq.h>
#include <linux/mempolicy.h>
#include <linux/freezer.h>
#include <linux/kallsyms.h>
#include <linux/debug_locks.h>

/*
* The per-CPU workqueue (if single thread, we always use the first
Expand Down Expand Up @@ -253,6 +255,17 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
work_release(work);
f(work);

if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
"%s/0x%08x/%d\n",
current->comm, preempt_count(),
current->pid);
printk(KERN_ERR " last function: ");
print_symbol("%s\n", (unsigned long)f);
debug_show_held_locks(current);
dump_stack();
}

spin_lock_irqsave(&cwq->lock, flags);
cwq->remove_sequence++;
wake_up(&cwq->work_done);
Expand Down

0 comments on commit d5abe66

Please sign in to comment.