fork: Explicity test for idle tasks in copy_thread
The architectures ia64 and parisc have special handling for the idle thread in copy_process. Add a flag named idle to kernel_clone_args and use it to explicity test if an idle process is being created. Fullfill the expectations of the rest of the copy_thread implemetations and pass a function pointer in .stack from fork_idle(). This makes what is happening in copy_thread better defined, and is useful to make idle threads less special. Link: https://lkml.kernel.org/r/20220506141512.516114-3-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
		@@ -342,7 +342,7 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 | 
			
		||||
	ia64_drop_fpu(p);	/* don't pick up stale state from a CPU's fph */
 | 
			
		||||
 | 
			
		||||
	if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
 | 
			
		||||
		if (unlikely(!user_stack_base)) {
 | 
			
		||||
		if (unlikely(args->idle)) {
 | 
			
		||||
			/* fork_idle() called us */
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -224,7 +224,7 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 | 
			
		||||
	if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
 | 
			
		||||
		/* kernel thread */
 | 
			
		||||
		memset(cregs, 0, sizeof(struct pt_regs));
 | 
			
		||||
		if (!usp) /* idle thread */
 | 
			
		||||
		if (args->idle) /* idle thread */
 | 
			
		||||
			return 0;
 | 
			
		||||
		/* Must exit via ret_from_kernel_thread in order
 | 
			
		||||
		 * to call schedule_tail()
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ struct kernel_clone_args {
 | 
			
		||||
	int cgroup;
 | 
			
		||||
	int io_thread;
 | 
			
		||||
	int kthread;
 | 
			
		||||
	int idle;
 | 
			
		||||
	struct cgroup *cgrp;
 | 
			
		||||
	struct css_set *cset;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -2544,12 +2544,21 @@ static inline void init_idle_pids(struct task_struct *idle)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int idle_dummy(void *dummy)
 | 
			
		||||
{
 | 
			
		||||
	/* This function is never called */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct task_struct * __init fork_idle(int cpu)
 | 
			
		||||
{
 | 
			
		||||
	struct task_struct *task;
 | 
			
		||||
	struct kernel_clone_args args = {
 | 
			
		||||
		.flags		= CLONE_VM,
 | 
			
		||||
		.stack		= (unsigned long)&idle_dummy,
 | 
			
		||||
		.stack_size	= (unsigned long)NULL,
 | 
			
		||||
		.kthread	= 1,
 | 
			
		||||
		.idle		= 1,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	task = copy_process(&init_struct_pid, 0, cpu_to_node(cpu), &args);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user