git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.5.x5
[linux-2.6.git]
/
kernel
/
kthread.c
diff --git
a/kernel/kthread.c
b/kernel/kthread.c
index
fc0767d
..
dbbc727
100644
(file)
--- a/
kernel/kthread.c
+++ b/
kernel/kthread.c
@@
-14,6
+14,12
@@
#include <linux/module.h>
#include <asm/semaphore.h>
#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. */
struct kthread_create_info
{
/* Information passed to kthread() from keventd. */
@@
-126,12
+132,13
@@
struct task_struct *kthread_create(int (*threadfn)(void *data),
init_completion(&create.started);
init_completion(&create.done);
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 {
work.func(work.data);
else {
-
schedule_work(
&work);
+
queue_work(helper_wq,
&work);
wait_for_completion(&create.done);
}
if (!IS_ERR(create.result)) {
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);
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);
+