X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fkthread.c;h=dbbc727ed2a9764d63cc8f68876e8efdc882c8f8;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=fc0767d8461a1d66c950fff2a4b6dcc9de0fcac6;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/kernel/kthread.c b/kernel/kthread.c index fc0767d84..dbbc727ed 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -14,6 +14,12 @@ #include #include +/* + * 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 (*threadfn)(void *data), 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); +