[patch] fix keventd execution dependency

From: Ingo Molnar
Date: Tue Sep 14 2004 - 06:38:16 EST



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.

Ingo

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: Ingo Molnar <mingo@xxxxxxx>

--- linux/kernel/kthread.c.orig
+++ linux/kernel/kthread.c
@@ -14,6 +14,12 @@
#include <linux/module.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
{
/* Information passed to kthread() from keventd. */
@@ -126,12 +132,13 @@ struct task_struct *kthread_create(int (
init_completion(&create.started);
init_completion(&create.done);

- /* If we're being called to start the first workqueue, we
- * can't use keventd. */
- if (!keventd_up())
+ /*
+ * The workqueue needs to start up first:
+ */
+ if (!helper_wq)
work.func(work.data);
else {
- schedule_work(&work);
+ queue_work(helper_wq, &work);
wait_for_completion(&create.done);
}
if (!IS_ERR(create.result)) {
@@ -183,3 +190,13 @@ int kthread_stop(struct task_struct *k)
return ret;
}
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);
+