diff --git a/[refs] b/[refs] index 085ccd0b55df..b7668720b13f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 83521d3eb8dd2dfb04dd78b4733e9766f61bb47e +refs/heads/master: 61e1a9ea4b425eb8c3b4965c35fe953bd881728f diff --git a/trunk/include/linux/kthread.h b/trunk/include/linux/kthread.h index 3fa786448db3..ebdd41fd1082 100644 --- a/trunk/include/linux/kthread.h +++ b/trunk/include/linux/kthread.h @@ -69,6 +69,18 @@ void kthread_bind(struct task_struct *k, unsigned int cpu); * was never called. */ int kthread_stop(struct task_struct *k); +/** + * kthread_stop_sem: stop a thread created by kthread_create(). + * @k: thread created by kthread_create(). + * @s: semaphore that @k waits on while idle. + * + * Does essentially the same thing as kthread_stop() above, but wakes + * @k by calling up(@s). + * + * Returns the result of threadfn(), or -EINTR if wake_up_process() + * was never called. */ +int kthread_stop_sem(struct task_struct *k, struct semaphore *s); + /** * kthread_should_stop: should this kthread return now? * diff --git a/trunk/kernel/kthread.c b/trunk/kernel/kthread.c index f50f174e92da..e75950a1092c 100644 --- a/trunk/kernel/kthread.c +++ b/trunk/kernel/kthread.c @@ -164,6 +164,12 @@ void kthread_bind(struct task_struct *k, unsigned int cpu) EXPORT_SYMBOL(kthread_bind); int kthread_stop(struct task_struct *k) +{ + return kthread_stop_sem(k, NULL); +} +EXPORT_SYMBOL(kthread_stop); + +int kthread_stop_sem(struct task_struct *k, struct semaphore *s) { int ret; @@ -178,7 +184,10 @@ int kthread_stop(struct task_struct *k) /* Now set kthread_should_stop() to true, and wake it up. */ kthread_stop_info.k = k; - wake_up_process(k); + if (s) + up(s); + else + wake_up_process(k); put_task_struct(k); /* Once it dies, reset stop ptr, gather result and we're done. */ @@ -189,7 +198,7 @@ int kthread_stop(struct task_struct *k) return ret; } -EXPORT_SYMBOL(kthread_stop); +EXPORT_SYMBOL(kthread_stop_sem); static __init int helper_init(void) {