kthread: introduce to_live_kthread()
"k->vfork_done != NULL" with a barrier() after to_kthread(k) in task_get_live_kthread(k) looks unclear, and sub-optimal because we load ->vfork_done twice. All we need is to ensure that we do not return to_kthread(NULL). Add a new trivial helper which loads/checks ->vfork_done once, this also looks more understandable. 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>
This commit is contained in:
		
							parent
							
								
									ec25e246b9
								
							
						
					
					
						commit
						4ecdafc808
					
				| @ -52,8 +52,21 @@ enum KTHREAD_BITS { | ||||
| 	KTHREAD_IS_PARKED, | ||||
| }; | ||||
| 
 | ||||
| #define to_kthread(tsk)	\ | ||||
| 	container_of((tsk)->vfork_done, struct kthread, exited) | ||||
| #define __to_kthread(vfork)	\ | ||||
| 	container_of(vfork, struct kthread, exited) | ||||
| 
 | ||||
| static inline struct kthread *to_kthread(struct task_struct *k) | ||||
| { | ||||
| 	return __to_kthread(k->vfork_done); | ||||
| } | ||||
| 
 | ||||
| static struct kthread *to_live_kthread(struct task_struct *k) | ||||
| { | ||||
| 	struct completion *vfork = ACCESS_ONCE(k->vfork_done); | ||||
| 	if (likely(vfork)) | ||||
| 		return __to_kthread(vfork); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * kthread_should_stop - should this kthread return now? | ||||
| @ -313,15 +326,8 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), | ||||
| 
 | ||||
| static struct kthread *task_get_live_kthread(struct task_struct *k) | ||||
| { | ||||
| 	struct kthread *kthread; | ||||
| 
 | ||||
| 	get_task_struct(k); | ||||
| 	kthread = to_kthread(k); | ||||
| 	/* It might have exited */ | ||||
| 	barrier(); | ||||
| 	if (k->vfork_done != NULL) | ||||
| 		return kthread; | ||||
| 	return NULL; | ||||
| 	return to_live_kthread(k); | ||||
| } | ||||
| 
 | ||||
| static void __kthread_unpark(struct task_struct *k, struct kthread *kthread) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user