From: Alan Stern Enhance the kthread API by adding kthread_stop_sem, for use in stopping threads that spend their idle time waiting on a semaphore. Signed-off-by: Alan Stern Signed-off-by: Andrew Morton --- include/linux/kthread.h | 12 ++++++++++++ kernel/kthread.c | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff -puN include/linux/kthread.h~add-kthread_stop_sem include/linux/kthread.h --- 25/include/linux/kthread.h~add-kthread_stop_sem Tue Sep 20 15:54:02 2005 +++ 25-akpm/include/linux/kthread.h Tue Sep 20 15:54:02 2005 @@ -70,6 +70,18 @@ void kthread_bind(struct task_struct *k, 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? * * When someone calls kthread_stop on your kthread, it will be woken diff -puN kernel/kthread.c~add-kthread_stop_sem kernel/kthread.c --- 25/kernel/kthread.c~add-kthread_stop_sem Tue Sep 20 15:54:02 2005 +++ 25-akpm/kernel/kthread.c Tue Sep 20 15:54:02 2005 @@ -165,6 +165,12 @@ 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; down(&kthread_stop_lock); @@ -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) { _