diff options
Diffstat (limited to 'kernel/kthread.c')
| -rw-r--r-- | kernel/kthread.c | 48 | 
1 files changed, 21 insertions, 27 deletions
| diff --git a/kernel/kthread.c b/kernel/kthread.c index cd50e99202b0..481951bf091d 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -55,7 +55,6 @@ enum KTHREAD_BITS {  	KTHREAD_IS_PER_CPU = 0,  	KTHREAD_SHOULD_STOP,  	KTHREAD_SHOULD_PARK, -	KTHREAD_IS_PARKED,  };  static inline void set_kthread_struct(void *kthread) @@ -177,14 +176,12 @@ void *kthread_probe_data(struct task_struct *task)  static void __kthread_parkme(struct kthread *self)  { -	__set_current_state(TASK_PARKED); -	while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) { -		if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags)) -			complete(&self->parked); +	for (;;) { +		set_current_state(TASK_PARKED); +		if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags)) +			break;  		schedule(); -		__set_current_state(TASK_PARKED);  	} -	clear_bit(KTHREAD_IS_PARKED, &self->flags);  	__set_current_state(TASK_RUNNING);  } @@ -194,6 +191,11 @@ void kthread_parkme(void)  }  EXPORT_SYMBOL_GPL(kthread_parkme); +void kthread_park_complete(struct task_struct *k) +{ +	complete_all(&to_kthread(k)->parked); +} +  static int kthread(void *_create)  {  	/* Copy data: it's on kthread's stack */ @@ -450,22 +452,16 @@ void kthread_unpark(struct task_struct *k)  {  	struct kthread *kthread = to_kthread(k); -	clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);  	/* -	 * We clear the IS_PARKED bit here as we don't wait -	 * until the task has left the park code. So if we'd -	 * park before that happens we'd see the IS_PARKED bit -	 * which might be about to be cleared. +	 * Newly created kthread was parked when the CPU was offline. +	 * The binding was lost and we need to set it again.  	 */ -	if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) { -		/* -		 * Newly created kthread was parked when the CPU was offline. -		 * The binding was lost and we need to set it again. -		 */ -		if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) -			__kthread_bind(k, kthread->cpu, TASK_PARKED); -		wake_up_state(k, TASK_PARKED); -	} +	if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) +		__kthread_bind(k, kthread->cpu, TASK_PARKED); + +	reinit_completion(&kthread->parked); +	clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); +	wake_up_state(k, TASK_PARKED);  }  EXPORT_SYMBOL_GPL(kthread_unpark); @@ -488,12 +484,10 @@ int kthread_park(struct task_struct *k)  	if (WARN_ON(k->flags & PF_EXITING))  		return -ENOSYS; -	if (!test_bit(KTHREAD_IS_PARKED, &kthread->flags)) { -		set_bit(KTHREAD_SHOULD_PARK, &kthread->flags); -		if (k != current) { -			wake_up_process(k); -			wait_for_completion(&kthread->parked); -		} +	set_bit(KTHREAD_SHOULD_PARK, &kthread->flags); +	if (k != current) { +		wake_up_process(k); +		wait_for_completion(&kthread->parked);  	}  	return 0; |