Commit d12ca525 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] fix keventd execution dependency

We dont want to execute off keventd since it might hold a semaphore our
callers hold too.  This can happen when kthread_create() is called from
within keventd.  This happened due to the IRQ threading patches but it
could happen with other code too.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent de68a62a
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
/*
* We dont want to execute off keventd since it might
* hold a semaphore our callers hold too:
*/
static struct workqueue_struct *helper_wq;
struct kthread_create_info struct kthread_create_info
{ {
/* Information passed to kthread() from keventd. */ /* Information passed to kthread() from keventd. */
...@@ -126,12 +132,13 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), ...@@ -126,12 +132,13 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
init_completion(&create.started); init_completion(&create.started);
init_completion(&create.done); init_completion(&create.done);
/* If we're being called to start the first workqueue, we /*
* can't use keventd. */ * The workqueue needs to start up first:
if (!keventd_up()) */
if (!helper_wq)
work.func(work.data); work.func(work.data);
else { else {
schedule_work(&work); queue_work(helper_wq, &work);
wait_for_completion(&create.done); wait_for_completion(&create.done);
} }
if (!IS_ERR(create.result)) { if (!IS_ERR(create.result)) {
...@@ -183,3 +190,13 @@ int kthread_stop(struct task_struct *k) ...@@ -183,3 +190,13 @@ int kthread_stop(struct task_struct *k)
return ret; return ret;
} }
EXPORT_SYMBOL(kthread_stop); EXPORT_SYMBOL(kthread_stop);
static __init int helper_init(void)
{
helper_wq = create_singlethread_workqueue("kthread");
BUG_ON(!helper_wq);
return 0;
}
core_initcall(helper_init);
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