[patch] fix keventd execution dependency

Ingo Molnar
2004-09-14T11:32:46Z

[-- Attachment #1: Type: text/plain, Size: 255 bytes --]

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

[-- Attachment #2: fix-keventd.patch --]
[-- Type: text/plain, Size: 1425 bytes --]

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@elte.hu>

--- 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);
+