aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kthread.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-04-29 18:05:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:25 -0400
commitb5c5442bb6bce0c67701d55124be561043a51faf (patch)
treef00a0fdcdb157fa4b8f54c6a31d3935b7c927aa6 /kernel/kthread.c
parent4ecdafc8084fe1d95bb59ed7753b345abcd586fb (diff)
kthread: kill task_get_live_kthread()
task_get_live_kthread() looks confusing and unneeded. It does get_task_struct() but only kthread_stop() needs this, it can be called even if the calller doesn't have a reference when we know that this kthread can't exit until we do kthread_stop(). kthread_park() and kthread_unpark() do not need get_task_struct(), the callers already have the reference. And it can not help if we can race with the exiting kthread anyway, kthread_park() can hang forever in this case. Change kthread_park() and kthread_unpark() to use to_live_kthread(), change kthread_stop() to do get_task_struct() by hand and remove task_get_live_kthread(). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Namhyung Kim <namhyung@kernel.org> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kthread.c')
-rw-r--r--kernel/kthread.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/kernel/kthread.c b/kernel/kthread.c
index a84dee265f94..9b12d65186f7 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -324,12 +324,6 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
324 return p; 324 return p;
325} 325}
326 326
327static struct kthread *task_get_live_kthread(struct task_struct *k)
328{
329 get_task_struct(k);
330 return to_live_kthread(k);
331}
332
333static void __kthread_unpark(struct task_struct *k, struct kthread *kthread) 327static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
334{ 328{
335 clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); 329 clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
@@ -356,11 +350,10 @@ static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
356 */ 350 */
357void kthread_unpark(struct task_struct *k) 351void kthread_unpark(struct task_struct *k)
358{ 352{
359 struct kthread *kthread = task_get_live_kthread(k); 353 struct kthread *kthread = to_live_kthread(k);
360 354
361 if (kthread) 355 if (kthread)
362 __kthread_unpark(k, kthread); 356 __kthread_unpark(k, kthread);
363 put_task_struct(k);
364} 357}
365 358
366/** 359/**
@@ -377,7 +370,7 @@ void kthread_unpark(struct task_struct *k)
377 */ 370 */
378int kthread_park(struct task_struct *k) 371int kthread_park(struct task_struct *k)
379{ 372{
380 struct kthread *kthread = task_get_live_kthread(k); 373 struct kthread *kthread = to_live_kthread(k);
381 int ret = -ENOSYS; 374 int ret = -ENOSYS;
382 375
383 if (kthread) { 376 if (kthread) {
@@ -390,7 +383,6 @@ int kthread_park(struct task_struct *k)
390 } 383 }
391 ret = 0; 384 ret = 0;
392 } 385 }
393 put_task_struct(k);
394 return ret; 386 return ret;
395} 387}
396 388
@@ -411,10 +403,13 @@ int kthread_park(struct task_struct *k)
411 */ 403 */
412int kthread_stop(struct task_struct *k) 404int kthread_stop(struct task_struct *k)
413{ 405{
414 struct kthread *kthread = task_get_live_kthread(k); 406 struct kthread *kthread;
415 int ret; 407 int ret;
416 408
417 trace_sched_kthread_stop(k); 409 trace_sched_kthread_stop(k);
410
411 get_task_struct(k);
412 kthread = to_live_kthread(k);
418 if (kthread) { 413 if (kthread) {
419 set_bit(KTHREAD_SHOULD_STOP, &kthread->flags); 414 set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
420 __kthread_unpark(k, kthread); 415 __kthread_unpark(k, kthread);
@@ -422,10 +417,9 @@ int kthread_stop(struct task_struct *k)
422 wait_for_completion(&kthread->exited); 417 wait_for_completion(&kthread->exited);
423 } 418 }
424 ret = k->exit_code; 419 ret = k->exit_code;
425
426 put_task_struct(k); 420 put_task_struct(k);
427 trace_sched_kthread_stop_ret(ret);
428 421
422 trace_sched_kthread_stop_ret(ret);
429 return ret; 423 return ret;
430} 424}
431EXPORT_SYMBOL(kthread_stop); 425EXPORT_SYMBOL(kthread_stop);