Commit 2139597d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] flush_workqueue(): detect excessive nesting

Add a debug check for workqueues nested more than three deep via the
direct-run-workqueue() path.
parent b9b52730
...@@ -47,6 +47,7 @@ struct cpu_workqueue_struct { ...@@ -47,6 +47,7 @@ struct cpu_workqueue_struct {
struct workqueue_struct *wq; struct workqueue_struct *wq;
task_t *thread; task_t *thread;
int run_depth; /* Detect run_workqueue() recursion depth */
} ____cacheline_aligned; } ____cacheline_aligned;
/* /*
...@@ -129,6 +130,13 @@ static inline void run_workqueue(struct cpu_workqueue_struct *cwq) ...@@ -129,6 +130,13 @@ static inline void run_workqueue(struct cpu_workqueue_struct *cwq)
* done. * done.
*/ */
spin_lock_irqsave(&cwq->lock, flags); spin_lock_irqsave(&cwq->lock, flags);
cwq->run_depth++;
if (cwq->run_depth > 3) {
/* morton gets to eat his hat */
printk("%s: recursion depth exceeded: %d\n",
__FUNCTION__, cwq->run_depth);
dump_stack();
}
while (!list_empty(&cwq->worklist)) { while (!list_empty(&cwq->worklist)) {
struct work_struct *work = list_entry(cwq->worklist.next, struct work_struct *work = list_entry(cwq->worklist.next,
struct work_struct, entry); struct work_struct, entry);
...@@ -146,6 +154,7 @@ static inline void run_workqueue(struct cpu_workqueue_struct *cwq) ...@@ -146,6 +154,7 @@ static inline void run_workqueue(struct cpu_workqueue_struct *cwq)
cwq->remove_sequence++; cwq->remove_sequence++;
wake_up(&cwq->work_done); wake_up(&cwq->work_done);
} }
cwq->run_depth--;
spin_unlock_irqrestore(&cwq->lock, flags); spin_unlock_irqrestore(&cwq->lock, flags);
} }
...@@ -275,6 +284,7 @@ struct workqueue_struct *create_workqueue(const char *name) ...@@ -275,6 +284,7 @@ struct workqueue_struct *create_workqueue(const char *name)
wq = kmalloc(sizeof(*wq), GFP_KERNEL); wq = kmalloc(sizeof(*wq), GFP_KERNEL);
if (!wq) if (!wq)
return NULL; return NULL;
memset(wq, 0, sizeof(*wq));
for (cpu = 0; cpu < NR_CPUS; cpu++) { for (cpu = 0; cpu < NR_CPUS; cpu++) {
if (!cpu_online(cpu)) if (!cpu_online(cpu))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment