Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5c5442b authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

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: default avatarOleg 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4ecdafc8
Loading
Loading
Loading
Loading
+7 −13
Original line number Original line Diff line number Diff line
@@ -324,12 +324,6 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
	return p;
	return p;
}
}


static struct kthread *task_get_live_kthread(struct task_struct *k)
{
	get_task_struct(k);
	return to_live_kthread(k);
}

static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
{
{
	clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
	clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
@@ -356,11 +350,10 @@ static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
 */
 */
void kthread_unpark(struct task_struct *k)
void kthread_unpark(struct task_struct *k)
{
{
	struct kthread *kthread = task_get_live_kthread(k);
	struct kthread *kthread = to_live_kthread(k);


	if (kthread)
	if (kthread)
		__kthread_unpark(k, kthread);
		__kthread_unpark(k, kthread);
	put_task_struct(k);
}
}


/**
/**
@@ -377,7 +370,7 @@ void kthread_unpark(struct task_struct *k)
 */
 */
int kthread_park(struct task_struct *k)
int kthread_park(struct task_struct *k)
{
{
	struct kthread *kthread = task_get_live_kthread(k);
	struct kthread *kthread = to_live_kthread(k);
	int ret = -ENOSYS;
	int ret = -ENOSYS;


	if (kthread) {
	if (kthread) {
@@ -390,7 +383,6 @@ int kthread_park(struct task_struct *k)
		}
		}
		ret = 0;
		ret = 0;
	}
	}
	put_task_struct(k);
	return ret;
	return ret;
}
}


@@ -411,10 +403,13 @@ int kthread_park(struct task_struct *k)
 */
 */
int kthread_stop(struct task_struct *k)
int kthread_stop(struct task_struct *k)
{
{
	struct kthread *kthread = task_get_live_kthread(k);
	struct kthread *kthread;
	int ret;
	int ret;


	trace_sched_kthread_stop(k);
	trace_sched_kthread_stop(k);

	get_task_struct(k);
	kthread = to_live_kthread(k);
	if (kthread) {
	if (kthread) {
		set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
		set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
		__kthread_unpark(k, kthread);
		__kthread_unpark(k, kthread);
@@ -422,10 +417,9 @@ int kthread_stop(struct task_struct *k)
		wait_for_completion(&kthread->exited);
		wait_for_completion(&kthread->exited);
	}
	}
	ret = k->exit_code;
	ret = k->exit_code;

	put_task_struct(k);
	put_task_struct(k);
	trace_sched_kthread_stop_ret(ret);


	trace_sched_kthread_stop_ret(ret);
	return ret;
	return ret;
}
}
EXPORT_SYMBOL(kthread_stop);
EXPORT_SYMBOL(kthread_stop);