Commit 36cb0e1c authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

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: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent c5febea0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
		}
+1 −1
Original line number Diff line number Diff line
@@ -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()
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ struct kernel_clone_args {
	int cgroup;
	int io_thread;
	int kthread;
	int idle;
	struct cgroup *cgrp;
	struct css_set *cset;
};
+9 −0
Original line number Diff line number Diff line
@@ -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);