linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Introduce CABA helper process tree
@ 2022-09-08 14:03 Pavel Tikhomirov
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
  2022-09-08 14:03 ` [PATCH v3 2/2] tests: Add CABA selftest Pavel Tikhomirov
  0 siblings, 2 replies; 9+ messages in thread
From: Pavel Tikhomirov @ 2022-09-08 14:03 UTC (permalink / raw)
  To: Eric Biederman, Alexander Viro, Christian Brauner, Andrei Vagin,
	linux-kernel
  Cc: Pavel Tikhomirov, Kees Cook, Ingo Molnar, Peter Zijlstra,
	Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
	Valentin Schneider, Andrew Morton, linux-ia64, linux-mm,
	linux-fsdevel, kernel

CABA = Closest Alive Born Ancestor

In Linux process tree we reparent children of a dying process to the
reaper, thus loosing information in which subtree the child was
originally born. This information can be useful to CRIU to restore
process trees right.

The idea of CABA tree is to keep reference to the closest "born"
ancestor in the process tree. In simple case if our "born" parent dies
(completely unhashed) CABA would then point to its "born" parent - our
"born" grand-parent. So CABA is always referencing closest "born"
(grand-)*parent in available processes.

Please see "Add CABA tree to task_struct" for deeper explanation, and
"tests: Add CABA selftest" for a small test and an actual example for
which we might need CABA.

Probably the original problem of restoring process tree with complex
sessions can be resolved by allowing sessions copying, like we do for
process group, but I'm not sure if that would be too secure to do it,
and if there would not be another similar resource in future. So I
prefere CABA.

Also we can use CABA not only for CRIU for restoring processes, but in
normal life when processes detach CABA will help to understand from
which place in process tree they were originally started from sshd/crond
or something else.

Hope my idea is not completely insane =)

I plan to have a talk on LPC 2022 about it https://lpc.events/event/16/contributions/1241/

CC: Eric Biederman <ebiederm@xmission.com>
CC: Kees Cook <keescook@chromium.org>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Ingo Molnar <mingo@redhat.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Juri Lelli <juri.lelli@redhat.com>
CC: Vincent Guittot <vincent.guittot@linaro.org>
CC: Dietmar Eggemann <dietmar.eggemann@arm.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ben Segall <bsegall@google.com>
CC: Mel Gorman <mgorman@suse.de>
CC: Daniel Bristot de Oliveira <bristot@redhat.com>
CC: Valentin Schneider <vschneid@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: linux-ia64@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mm@kvack.org
CC: linux-fsdevel@vger.kernel.org
CC: kernel@openvz.org

Pavel Tikhomirov (2):
  Add CABA tree to task_struct
  tests: Add CABA selftest

 arch/ia64/kernel/mca.c                   |   3 +
 fs/exec.c                                |   1 +
 fs/proc/array.c                          |  20 +
 include/linux/sched.h                    |   7 +
 init/init_task.c                         |   3 +
 kernel/exit.c                            |  21 +
 kernel/fork.c                            |   4 +
 tools/testing/selftests/Makefile         |   1 +
 tools/testing/selftests/caba/.gitignore  |   1 +
 tools/testing/selftests/caba/Makefile    |   7 +
 tools/testing/selftests/caba/caba_test.c | 509 +++++++++++++++++++++++
 tools/testing/selftests/caba/config      |   1 +
 12 files changed, 578 insertions(+)
 create mode 100644 tools/testing/selftests/caba/.gitignore
 create mode 100644 tools/testing/selftests/caba/Makefile
 create mode 100644 tools/testing/selftests/caba/caba_test.c
 create mode 100644 tools/testing/selftests/caba/config

-- 
2.37.1



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 [PATCH v3 0/2] Introduce CABA helper process tree Pavel Tikhomirov
@ 2022-09-08 14:03 ` Pavel Tikhomirov
  2022-09-08 21:29   ` kernel test robot
                     ` (4 more replies)
  2022-09-08 14:03 ` [PATCH v3 2/2] tests: Add CABA selftest Pavel Tikhomirov
  1 sibling, 5 replies; 9+ messages in thread
From: Pavel Tikhomirov @ 2022-09-08 14:03 UTC (permalink / raw)
  To: Eric Biederman, Alexander Viro, Christian Brauner, Andrei Vagin,
	linux-kernel
  Cc: Pavel Tikhomirov, Kees Cook, Ingo Molnar, Peter Zijlstra,
	Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
	Valentin Schneider, Andrew Morton, linux-ia64, linux-mm,
	linux-fsdevel, kernel

In linux after parent (father) process dies, children processes are
moved (reparented) to a reaper process. Roughly speaking:

1) If father has other yet alive thread, this thread would be a reaper.

2) Else if there is father's ancestor (with no pidns level change in the
middle), which has PR_SET_CHILD_SUBREAPER set, this ancestor would be a
reaper.

3) Else father's pidns init would be a reaper for fathers children.

The problem with this for CRIU is that when CRIU comes to dump processes
it does not know the order in which processes and their resources were
created. And processes can have resources which a) can only be inherited
when we clone processes, b) can only be created by specific processes
and c) are shared between several processes (the example of such a
resource is process session). For such resources CRIU restore would need
to re-invent such order of process creation which at the same time
creates the desired process tree topology and allows to inherit all
resources right.

When process reparenting involves child-sub-reapers one can drastically
mix processes in process tree so that it is not obvious how to restore
everything right.

So this is what we came up with to help CRIU to overcome this problem:

CABA = Closest Alive Born Ancestor
CABD = Closest Alive Born Descendant

We want to put processes in one more tree - CABA tree. This tree is not
affecting reparenting or process creation in any way except for
providing a new information to CRIU so that we can understand from where
the reparented child had reparented, though original father is already
dead and probably a fathers father too, we can still have information
about the process which is still alive and was originally a parent of
process sequence (of already dead processes) which lead to us - CABA.

CC: Eric Biederman <ebiederm@xmission.com>
CC: Kees Cook <keescook@chromium.org>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Ingo Molnar <mingo@redhat.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Juri Lelli <juri.lelli@redhat.com>
CC: Vincent Guittot <vincent.guittot@linaro.org>
CC: Dietmar Eggemann <dietmar.eggemann@arm.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ben Segall <bsegall@google.com>
CC: Mel Gorman <mgorman@suse.de>
CC: Daniel Bristot de Oliveira <bristot@redhat.com>
CC: Valentin Schneider <vschneid@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: linux-ia64@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mm@kvack.org
CC: linux-fsdevel@vger.kernel.org
CC: kernel@openvz.org

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

--
v2: fix unused variables reported-by: kernel test robot <lkp@intel.com>
v3: - on fork set caba to current, so that caba is always a process
      which had initiated our creation, even for CLONE_PARENT case
    - move caba update to a later stage (to __unhash_process), so that
      zombies can be somebodies caba until fully released
---
 arch/ia64/kernel/mca.c |  3 +++
 fs/exec.c              |  1 +
 fs/proc/array.c        | 20 ++++++++++++++++++++
 include/linux/sched.h  |  7 +++++++
 init/init_task.c       |  3 +++
 kernel/exit.c          | 21 +++++++++++++++++++++
 kernel/fork.c          |  4 ++++
 7 files changed, 59 insertions(+)

diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index c62a66710ad6..5e561994cff7 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1793,6 +1793,9 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
 	p->parent = p->real_parent = p->group_leader = p;
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
+	p->caba = p;
+	INIT_LIST_HEAD(&p->cabds);
+	INIT_LIST_HEAD(&p->cabd);
 	strncpy(p->comm, type, sizeof(p->comm)-1);
 }
 
diff --git a/fs/exec.c b/fs/exec.c
index 9a5ca7b82bfc..8caaa03739ab 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1139,6 +1139,7 @@ static int de_thread(struct task_struct *tsk)
 
 		list_replace_rcu(&leader->tasks, &tsk->tasks);
 		list_replace_init(&leader->sibling, &tsk->sibling);
+		list_replace_init(&leader->cabd, &tsk->cabd);
 
 		tsk->group_leader = tsk;
 		leader->group_leader = tsk;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 99fcbfda8e25..5fd70aebd52d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -154,11 +154,28 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	const struct cred *cred;
 	pid_t ppid, tpid = 0, tgid, ngid;
 	unsigned int max_fds = 0;
+#ifdef CONFIG_PID_NS
+	struct task_struct *caba;
+	struct pid *caba_pid;
+	int caba_level = 0;
+	pid_t caba_pids[MAX_PID_NS_LEVEL] = {};
+#endif
 
 	rcu_read_lock();
 	ppid = pid_alive(p) ?
 		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
 
+#ifdef CONFIG_PID_NS
+	caba = rcu_dereference(p->caba);
+	caba_pid = get_task_pid(caba, PIDTYPE_PID);
+	if (caba_pid) {
+		caba_level = caba_pid->level;
+		for (g = ns->level; g <= caba_level; g++)
+			caba_pids[g] = task_pid_nr_ns(caba, caba_pid->numbers[g].ns);
+		put_pid(caba_pid);
+	}
+#endif
+
 	tracer = ptrace_parent(p);
 	if (tracer)
 		tpid = task_pid_nr_ns(tracer, ns);
@@ -217,6 +234,9 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	seq_puts(m, "\nNSsid:");
 	for (g = ns->level; g <= pid->level; g++)
 		seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
+	seq_puts(m, "\nNScaba:");
+	for (g = ns->level; g <= caba_level; g++)
+		seq_put_decimal_ull(m, "\t", caba_pids[g]);
 #endif
 	seq_putc(m, '\n');
 }
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e7b2f8a5c711..b30a2ccf1180 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -975,6 +975,13 @@ struct task_struct {
 	struct list_head		sibling;
 	struct task_struct		*group_leader;
 
+	/* Closest Alive Born Ancestor process: */
+	struct task_struct __rcu	*caba;
+
+	/* Closest Alive Born Descendants list: */
+	struct list_head		cabds;
+	struct list_head		cabd;
+
 	/*
 	 * 'ptraced' is the list of tasks this task is using ptrace() on.
 	 *
diff --git a/init/init_task.c b/init/init_task.c
index ff6c4b9bfe6b..439da3b04dde 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -109,6 +109,9 @@ struct task_struct init_task
 	.children	= LIST_HEAD_INIT(init_task.children),
 	.sibling	= LIST_HEAD_INIT(init_task.sibling),
 	.group_leader	= &init_task,
+	.caba		= &init_task,
+	.cabds		= LIST_HEAD_INIT(init_task.cabds),
+	.cabd		= LIST_HEAD_INIT(init_task.cabd),
 	RCU_POINTER_INITIALIZER(real_cred, &init_cred),
 	RCU_POINTER_INITIALIZER(cred, &init_cred),
 	.comm		= INIT_TASK_COMM,
diff --git a/kernel/exit.c b/kernel/exit.c
index 84021b24f79e..32e4a380861d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -71,9 +71,29 @@
 #include <asm/unistd.h>
 #include <asm/mmu_context.h>
 
+static void forget_caba(struct task_struct *caba)
+{
+	struct task_struct *p, *t, *new_caba;
+
+	if (list_empty(&caba->cabds))
+		return;
+
+	if (!thread_group_leader(caba))
+		new_caba = caba->group_leader;
+	else
+		new_caba = caba->caba;
+
+	list_for_each_entry(p, &caba->cabds, cabd) {
+		for_each_thread(p, t)
+			RCU_INIT_POINTER(t->caba, new_caba);
+	}
+	list_splice_tail_init(&caba->cabds, &new_caba->cabds);
+}
+
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
 	nr_threads--;
+	forget_caba(p);
 	detach_pid(p, PIDTYPE_PID);
 	if (group_dead) {
 		detach_pid(p, PIDTYPE_TGID);
@@ -82,6 +102,7 @@ static void __unhash_process(struct task_struct *p, bool group_dead)
 
 		list_del_rcu(&p->tasks);
 		list_del_init(&p->sibling);
+		list_del_init(&p->cabd);
 		__this_cpu_dec(process_counts);
 	}
 	list_del_rcu(&p->thread_group);
diff --git a/kernel/fork.c b/kernel/fork.c
index 90c85b17bf69..a14ee9f1acb1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2139,6 +2139,8 @@ static __latent_entropy struct task_struct *copy_process(
 	p->flags |= PF_FORKNOEXEC;
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
+	INIT_LIST_HEAD(&p->cabds);
+	INIT_LIST_HEAD(&p->cabd);
 	rcu_copy_process(p);
 	p->vfork_done = NULL;
 	spin_lock_init(&p->alloc_lock);
@@ -2402,6 +2404,7 @@ static __latent_entropy struct task_struct *copy_process(
 		p->parent_exec_id = current->self_exec_id;
 		p->exit_signal = args->exit_signal;
 	}
+	p->caba = current;
 
 	klp_copy_process(p);
 
@@ -2455,6 +2458,7 @@ static __latent_entropy struct task_struct *copy_process(
 			p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
 							 p->real_parent->signal->is_child_subreaper;
 			list_add_tail(&p->sibling, &p->real_parent->children);
+			list_add_tail(&p->cabd, &p->caba->cabds);
 			list_add_tail_rcu(&p->tasks, &init_task.tasks);
 			attach_pid(p, PIDTYPE_TGID);
 			attach_pid(p, PIDTYPE_PGID);
-- 
2.37.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/2] tests: Add CABA selftest
  2022-09-08 14:03 [PATCH v3 0/2] Introduce CABA helper process tree Pavel Tikhomirov
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
@ 2022-09-08 14:03 ` Pavel Tikhomirov
  1 sibling, 0 replies; 9+ messages in thread
From: Pavel Tikhomirov @ 2022-09-08 14:03 UTC (permalink / raw)
  To: Eric Biederman, Alexander Viro, Christian Brauner, Andrei Vagin,
	linux-kernel
  Cc: Pavel Tikhomirov, Kees Cook, Ingo Molnar, Peter Zijlstra,
	Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
	Valentin Schneider, Andrew Morton, linux-ia64, linux-mm,
	linux-fsdevel, kernel

This test creates a "tricky" example process tree where session leaders
of two sessions are children of pid namespace init, also they have their
own children, leader of session A has child with session B and leader
from session B has child with session A.

We check that Closest Alive Born Ancestor tree is right for this case.
This case illustrates how CABA tree helps to understand order of
creation between sessions.

CC: Eric Biederman <ebiederm@xmission.com>
CC: Kees Cook <keescook@chromium.org>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Ingo Molnar <mingo@redhat.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Juri Lelli <juri.lelli@redhat.com>
CC: Vincent Guittot <vincent.guittot@linaro.org>
CC: Dietmar Eggemann <dietmar.eggemann@arm.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ben Segall <bsegall@google.com>
CC: Mel Gorman <mgorman@suse.de>
CC: Daniel Bristot de Oliveira <bristot@redhat.com>
CC: Valentin Schneider <vschneid@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: linux-ia64@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mm@kvack.org
CC: linux-fsdevel@vger.kernel.org
CC: kernel@openvz.org

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

--
v3: fix codding style
---
 tools/testing/selftests/Makefile         |   1 +
 tools/testing/selftests/caba/.gitignore  |   1 +
 tools/testing/selftests/caba/Makefile    |   7 +
 tools/testing/selftests/caba/caba_test.c | 509 +++++++++++++++++++++++
 tools/testing/selftests/caba/config      |   1 +
 5 files changed, 519 insertions(+)
 create mode 100644 tools/testing/selftests/caba/.gitignore
 create mode 100644 tools/testing/selftests/caba/Makefile
 create mode 100644 tools/testing/selftests/caba/caba_test.c
 create mode 100644 tools/testing/selftests/caba/config

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index c2064a35688b..d545bd9e3637 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -3,6 +3,7 @@ TARGETS += alsa
 TARGETS += arm64
 TARGETS += bpf
 TARGETS += breakpoints
+TARGETS += caba
 TARGETS += capabilities
 TARGETS += cgroup
 TARGETS += clone3
diff --git a/tools/testing/selftests/caba/.gitignore b/tools/testing/selftests/caba/.gitignore
new file mode 100644
index 000000000000..aa2c55b774e2
--- /dev/null
+++ b/tools/testing/selftests/caba/.gitignore
@@ -0,0 +1 @@
+caba_test
diff --git a/tools/testing/selftests/caba/Makefile b/tools/testing/selftests/caba/Makefile
new file mode 100644
index 000000000000..4260145c3747
--- /dev/null
+++ b/tools/testing/selftests/caba/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for caba selftests.
+CFLAGS = -g -I../../../../usr/include/ -Wall -O2
+
+TEST_GEN_FILES += caba_test
+
+include ../lib.mk
diff --git a/tools/testing/selftests/caba/caba_test.c b/tools/testing/selftests/caba/caba_test.c
new file mode 100644
index 000000000000..a89c4b96393b
--- /dev/null
+++ b/tools/testing/selftests/caba/caba_test.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/mount.h>
+#include <sys/user.h>
+
+#include "../kselftest_harness.h"
+
+#ifndef CLONE_NEWPID
+#define CLONE_NEWPID 0x20000000	/* New pid namespace */
+#endif
+
+/* Attempt to de-conflict with the selftests tree. */
+#ifndef SKIP
+#define SKIP(s, ...)	XFAIL(s, ##__VA_ARGS__)
+#endif
+
+struct process {
+	pid_t pid;
+	pid_t real;
+	pid_t caba;
+	int sks[2];
+	int dead;
+};
+
+struct process *processes;
+int nr_processes = 8;
+int current;
+
+static void cleanup(void)
+{
+	kill(processes[0].pid, SIGKILL);
+	/* It's enough to kill pidns init for others to die */
+	kill(processes[1].pid, SIGKILL);
+}
+
+enum commands {
+	TEST_FORK,
+	TEST_WAIT,
+	TEST_SUBREAPER,
+	TEST_SETSID,
+	TEST_DIE,
+	/* unused */
+	TEST_GETSID,
+	TEST_SETNS,
+	TEST_SETPGID,
+	TEST_GETPGID,
+	TEST_GETPPID,
+};
+
+struct command {
+	enum commands	cmd;
+	int		arg1;
+	int		arg2;
+};
+
+static void handle_command(void);
+
+static void mainloop(void)
+{
+	while (1)
+		handle_command();
+}
+
+#define CLONE_STACK_SIZE 4096
+#define __stack_aligned__ __attribute__((aligned(16)))
+/* All arguments should be above stack, because it grows down */
+struct clone_args {
+	char stack[CLONE_STACK_SIZE] __stack_aligned__;
+	char stack_ptr[0];
+	int id;
+};
+
+static int get_real_pid(void)
+{
+	char buf[11];
+	int ret;
+
+	ret = readlink("/proc/self", buf, sizeof(buf)-1);
+	if (ret <= 0) {
+		fprintf(stderr, "%d: readlink /proc/self :%m", current);
+		return -1;
+	}
+	buf[ret] = '\0';
+
+	processes[current].real = atoi(buf);
+	return 0;
+}
+
+static int clone_func(void *_arg)
+{
+	struct clone_args *args = (struct clone_args *) _arg;
+
+	current = args->id;
+
+	if (get_real_pid())
+		exit(1);
+
+	printf("%3d: Hello. My pid is %d\n", args->id, getpid());
+	mainloop();
+	exit(0);
+}
+
+static int make_child(int id, int flags)
+{
+	struct clone_args args;
+	pid_t cid;
+
+	args.id = id;
+
+	cid = clone(clone_func, args.stack_ptr,
+			flags | SIGCHLD, &args);
+
+	if (cid < 0)
+		fprintf(stderr, "clone(%d, %d) :%m", id, flags);
+
+	processes[id].pid = cid;
+
+	return cid;
+}
+
+static int open_proc(void)
+{
+	int fd;
+	char proc_mountpoint[] = "/tmp/.caba_test.proc.XXXXXX";
+
+	if (mkdtemp(proc_mountpoint) == NULL) {
+		fprintf(stderr, "mkdtemp failed %s :%m\n", proc_mountpoint);
+		return -1;
+	}
+
+	if (mount("proc", proc_mountpoint, "proc",
+		  MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL)) {
+		fprintf(stderr, "mount proc failed :%m\n");
+		rmdir(proc_mountpoint);
+		return -1;
+	}
+
+	fd = open(proc_mountpoint, O_RDONLY | O_DIRECTORY, 0);
+	if (fd < 0)
+		fprintf(stderr, "can't open proc :%m\n");
+
+	if (umount2(proc_mountpoint, MNT_DETACH)) {
+		fprintf(stderr, "can't umount proc :%m\n");
+		goto err_close;
+	}
+
+	if (rmdir(proc_mountpoint)) {
+		fprintf(stderr, "can't remove tmp dir :%m\n");
+		goto err_close;
+	}
+
+	return fd;
+err_close:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+static int open_pidns(int pid)
+{
+	int proc, fd;
+	char pidns_path[PATH_MAX];
+
+	proc = open_proc();
+	if (proc < 0) {
+		fprintf(stderr, "open proc\n");
+		return -1;
+	}
+
+	sprintf(pidns_path, "%d/ns/pid", pid);
+	fd = openat(proc, pidns_path, O_RDONLY);
+	if (fd == -1)
+		fprintf(stderr, "open pidns fd\n");
+
+	close(proc);
+	return fd;
+}
+
+static int setns_pid(int pid, int nstype)
+{
+	int pidns, ret;
+
+	pidns = open_pidns(pid);
+	if (pidns < 0)
+		return -1;
+
+	ret = setns(pidns, nstype);
+	if (ret == -1)
+		fprintf(stderr, "setns :%m\n");
+
+	close(pidns);
+	return ret;
+}
+
+static void handle_command(void)
+{
+	int sk = processes[current].sks[0], ret, status = 0;
+	struct command cmd;
+
+	ret = read(sk, &cmd, sizeof(cmd));
+	if (ret != sizeof(cmd)) {
+		fprintf(stderr, "Unable to get command :%m\n");
+		goto err;
+	}
+
+	switch (cmd.cmd) {
+	case TEST_FORK:
+		{
+			pid_t pid;
+
+			pid = make_child(cmd.arg1, cmd.arg2);
+			if (pid == -1) {
+				status = -1;
+				goto err;
+			}
+
+			printf("%3d: fork(%d, %x) = %d\n",
+					current, cmd.arg1, cmd.arg2, pid);
+			processes[cmd.arg1].pid = pid;
+		}
+		break;
+	case TEST_WAIT:
+		printf("%3d: wait(%d) = %d\n", current,
+				cmd.arg1, processes[cmd.arg1].pid);
+
+		if (waitpid(processes[cmd.arg1].pid, NULL, 0) == -1) {
+			fprintf(stderr, "waitpid(%d) :%m\n", processes[cmd.arg1].pid);
+			status = -1;
+		}
+		break;
+	case TEST_SUBREAPER:
+		printf("%3d: subreaper(%d)\n", current, cmd.arg1);
+		if (prctl(PR_SET_CHILD_SUBREAPER, cmd.arg1, 0, 0, 0) == -1) {
+			fprintf(stderr, "PR_SET_CHILD_SUBREAPER :%m\n");
+			status = -1;
+		}
+		break;
+	case TEST_SETSID:
+		printf("%3d: setsid()\n", current);
+		if (setsid() == -1) {
+			fprintf(stderr, "setsid :%m\n");
+			status = -1;
+		}
+		break;
+	case TEST_GETSID:
+		printf("%3d: getsid()\n", current);
+		status = getsid(getpid());
+		if (status == -1)
+			fprintf(stderr, "getsid :%m\n");
+		break;
+	case TEST_SETPGID:
+		printf("%3d: setpgid(%d, %d)\n", current, cmd.arg1, cmd.arg2);
+		if (setpgid(processes[cmd.arg1].pid, processes[cmd.arg2].pid) == -1) {
+			fprintf(stderr, "setpgid :%m\n");
+			status = -1;
+		}
+		break;
+	case TEST_GETPGID:
+		printf("%3d: getpgid()\n", current);
+		status = getpgid(0);
+		if (status == -1)
+			fprintf(stderr, "getpgid :%m\n");
+		break;
+	case TEST_GETPPID:
+		printf("%3d: getppid()\n", current);
+		status = getppid();
+		if (status == -1)
+			fprintf(stderr, "getppid :%m\n");
+		break;
+	case TEST_SETNS:
+		printf("%3d: setns(%d, %d) = %d\n", current,
+				cmd.arg1, cmd.arg2, processes[cmd.arg1].pid);
+		setns_pid(processes[cmd.arg1].pid, cmd.arg2);
+
+		break;
+	case TEST_DIE:
+		printf("%3d: die()\n", current);
+		processes[current].dead = 1;
+		shutdown(sk, SHUT_RDWR);
+		exit(0);
+	}
+
+	ret = write(sk, &status, sizeof(status));
+	if (ret != sizeof(status)) {
+		fprintf(stderr, "Unable to answer :%m\n");
+		goto err;
+	}
+
+	if (status < 0)
+		goto err;
+
+	return;
+err:
+	shutdown(sk, SHUT_RDWR);
+	exit(1);
+}
+
+static int send_command(int id, enum commands op, int arg1, int arg2)
+{
+	int sk = processes[id].sks[1], ret, status;
+	struct command cmd = {op, arg1, arg2};
+
+	if (op == TEST_FORK) {
+		if (processes[arg1].pid) {
+			fprintf(stderr, "%d is busy :%m\n", arg1);
+			return -1;
+		}
+	}
+
+	ret = write(sk, &cmd, sizeof(cmd));
+	if (ret != sizeof(cmd)) {
+		fprintf(stderr, "Unable to send command :%m\n");
+		goto err;
+	}
+
+	status = 0;
+	ret = read(sk, &status, sizeof(status));
+	if (ret != sizeof(status) && !(status == 0 && op == TEST_DIE)) {
+		fprintf(stderr, "Unable to get answer :%m\n");
+		goto err;
+	}
+
+	if (status != -1 && (op == TEST_GETSID || op == TEST_GETPGID || op == TEST_GETPPID))
+		return status;
+
+	if (status) {
+		fprintf(stderr, "The command(%d, %d, %d) failed :%m\n", op, arg1, arg2);
+		goto err;
+	}
+
+	return 0;
+err:
+	cleanup();
+	exit(1);
+}
+
+static int get_caba(int pid, int *caba)
+{
+	char buf[64], *str;
+	FILE *fp;
+	size_t n;
+
+	if (!pid)
+		snprintf(buf, sizeof(buf), "/proc/self/status");
+	else
+		snprintf(buf, sizeof(buf), "/proc/%d/status", pid);
+
+	fp = fopen(buf, "r");
+	if (!fp) {
+		perror("fopen");
+		return -1;
+	}
+
+	str = NULL;
+	while (getline(&str, &n, fp) != -1) {
+		if (strncmp(str, "NScaba:", 7) == 0) {
+			if (str[7] == '\0') {
+				*caba = 0;
+			} else {
+				if (sscanf(str+7, "%d", caba) != 1) {
+					perror("sscanf");
+					goto err;
+				}
+			}
+
+			fclose(fp);
+			free(str);
+			return 0;
+		}
+	}
+err:
+	free(str);
+	fclose(fp);
+	return -1;
+}
+
+static bool caba_supported(void)
+{
+	int caba;
+
+	return !get_caba(0, &caba);
+}
+
+FIXTURE(caba) {
+};
+
+FIXTURE_SETUP(caba)
+{
+	bool ret;
+
+	ret = caba_supported();
+	ASSERT_GE(ret, 0);
+	if (!ret)
+		SKIP(return, "CABA is not supported");
+}
+
+FIXTURE_TEARDOWN(caba)
+{
+	bool ret;
+
+	ret = caba_supported();
+	ASSERT_GE(ret, 0);
+	if (!ret)
+		SKIP(return, "CABA is not supported");
+
+	cleanup();
+}
+
+TEST_F(caba, complex_sessions)
+{
+	int ret, i, pid, caba;
+
+	ret = caba_supported();
+	ASSERT_GE(ret, 0);
+	if (!ret)
+		SKIP(return, "CABA is not supported");
+
+	processes = mmap(NULL, PAGE_SIZE,
+			 PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS,
+			 0, 0);
+	ASSERT_NE(processes, MAP_FAILED);
+	for (i = 0; i < nr_processes; i++) {
+		ret = socketpair(PF_UNIX, SOCK_STREAM, 0, processes[i].sks);
+		ASSERT_EQ(ret, 0);
+	}
+
+	/*
+	 * Create init:
+	 * (pid, sid)
+	 * (1, 1)
+	 */
+	pid = make_child(0, 0); ASSERT_GT(pid, 0);
+	ret = send_command(0, TEST_FORK,	  1, CLONE_NEWPID);
+	ASSERT_EQ(ret, 0);
+	ret = send_command(1, TEST_SETSID,	  0, 0);
+	ASSERT_EQ(ret, 0);
+
+	/*
+	 * Create sequence of processes from one session:
+	 * (pid, sid)
+	 * (1, 1)---(2, 2)---(3, 2)---(4, 2)---(5, 2)
+	 */
+	ret = send_command(1, TEST_FORK,	  2, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(2, TEST_SETSID,	  0, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(2, TEST_FORK,	  3, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(3, TEST_FORK,	  4, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(4, TEST_FORK,	  5, 0); ASSERT_EQ(ret, 0);
+	/*
+	 * Create another session in the middle of first one:
+	 * (pid, sid)
+	 * (1, 1)---(2, 2)---(3, 2)---(4, 4)-+-(5, 2)
+	 *                                   `-(6, 4)---(7, 4)
+	 */
+	ret = send_command(4, TEST_SETSID,	  0, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(4, TEST_FORK,	  6, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(6, TEST_FORK,	  7, 0); ASSERT_EQ(ret, 0);
+
+	/*
+	 * Kill 6 while having 2 as child-sub-reaper:
+	 * (pid, sid)
+	 * (1, 1)---(2, 2)---(3, 2)---(4, 4)-+-(5, 2)
+	 *                 `-(7, 4)
+	 */
+	ret = send_command(2, TEST_SUBREAPER, 1, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(6, TEST_DIE,	  0, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(4, TEST_WAIT,	  6, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(2, TEST_SUBREAPER, 0, 0); ASSERT_EQ(ret, 0);
+
+	/*
+	 * Kill 3:
+	 * (pid, sid)
+	 * (1, 1)-+-(2, 2)---(7, 4)
+	 *        `-(4, 4)---(5, 2)
+	 * note: This is a "tricky" session tree example where it's not obvious
+	 * whether sid 2 was created first or sid 4 when creating the tree.
+	 */
+	ret = send_command(3, TEST_DIE,	  0, 0); ASSERT_EQ(ret, 0);
+	ret = send_command(2, TEST_WAIT,	  3, 0); ASSERT_EQ(ret, 0);
+
+	/*
+	 * CABA tree for this would be:
+	 * (pid, sid)
+	 * (1, 1)---(2, 2)---(4, 4)-+-(5, 2)
+	 *                          `-(7, 4)
+	 * note: CABA allows us to understand that session 2 was created first.
+	 */
+	ret = get_caba(processes[2].real, &caba);
+	ASSERT_EQ(ret, 0); ASSERT_EQ(caba, processes[1].real);
+	ret = get_caba(processes[4].real, &caba);
+	ASSERT_EQ(ret, 0); ASSERT_EQ(caba, processes[2].real);
+	ret = get_caba(processes[5].real, &caba);
+	ASSERT_EQ(ret, 0); ASSERT_EQ(caba, processes[4].real);
+	ret = get_caba(processes[7].real, &caba);
+	ASSERT_EQ(ret, 0); ASSERT_EQ(caba, processes[4].real);
+}
+
+TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/caba/config b/tools/testing/selftests/caba/config
new file mode 100644
index 000000000000..eae7bdaa3790
--- /dev/null
+++ b/tools/testing/selftests/caba/config
@@ -0,0 +1 @@
+CONFIG_PID_NS=y
-- 
2.37.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
@ 2022-09-08 21:29   ` kernel test robot
  2022-09-08 22:15     ` Pavel Tikhomirov
  2022-09-08 22:09   ` [PATCH v4 " Pavel Tikhomirov
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: kernel test robot @ 2022-09-08 21:29 UTC (permalink / raw)
  To: Pavel Tikhomirov, Eric Biederman, Alexander Viro,
	Christian Brauner, Andrei Vagin, linux-kernel
  Cc: kbuild-all, Pavel Tikhomirov, Kees Cook, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman,
	Daniel Bristot de Oliveira, Valentin Schneider, Andrew Morton,
	Linux Memory Management List, linux-ia64, linux-fsdevel, kernel

Hi Pavel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on kees/for-next/execve tip/sched/core linus/master v6.0-rc4 next-20220908]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
config: s390-randconfig-s043-20220907 (https://download.01.org/0day-ci/archive/20220909/202209090529.EL54HX2U-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/17a897a33137d4f49f99c8be8d619f6f711fccdb
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
        git checkout 17a897a33137d4f49f99c8be8d619f6f711fccdb
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

sparse warnings: (new ones prefixed by >>)
   kernel/fork.c:1307:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct file *[assigned] old_exe_file @@     got struct file [noderef] __rcu *[assigned] __ret @@
   kernel/fork.c:1307:22: sparse:     expected struct file *[assigned] old_exe_file
   kernel/fork.c:1307:22: sparse:     got struct file [noderef] __rcu *[assigned] __ret
   kernel/fork.c:1638:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:1638:38: sparse:     expected struct refcount_struct [usertype] *r
   kernel/fork.c:1638:38: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1647:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1647:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1647:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1648:9: sparse:     expected void const *
   kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1648:9: sparse:     expected void const *
   kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1648:9: sparse:     expected void const *
   kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1649:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1649:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1649:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:1742:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct arch_spinlock_t [usertype] *lp @@     got struct arch_spinlock_t [noderef] __rcu * @@
   kernel/fork.c:1742:9: sparse:     expected struct arch_spinlock_t [usertype] *lp
   kernel/fork.c:1742:9: sparse:     got struct arch_spinlock_t [noderef] __rcu *
   kernel/fork.c:2077:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2077:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2077:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2081:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2081:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2081:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2403:32: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct * @@
   kernel/fork.c:2403:32: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:2403:32: sparse:     got struct task_struct *
>> kernel/fork.c:2407:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct * @@
   kernel/fork.c:2407:17: sparse:     expected struct task_struct [noderef] __rcu *caba
   kernel/fork.c:2407:17: sparse:     got struct task_struct *
   kernel/fork.c:2413:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2413:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2413:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2460:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2460:54: sparse:     expected struct list_head *head
   kernel/fork.c:2460:54: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2461:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2461:51: sparse:     expected struct list_head *head
   kernel/fork.c:2461:51: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2482:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2482:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2482:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2503:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2503:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2503:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2530:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/fork.c:2530:28: sparse:     expected struct sighand_struct *sighand
   kernel/fork.c:2530:28: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/fork.c:2559:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2559:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2559:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2561:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2561:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2561:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2997:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/fork.c:2997:24: sparse:     expected struct task_struct *[assigned] parent
   kernel/fork.c:2997:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:3078:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct const [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:3078:43: sparse:     expected struct refcount_struct const [usertype] *r
   kernel/fork.c:3078:43: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:2122:22: sparse: sparse: dereference of noderef expression
   kernel/fork.c: note: in included file (through arch/s390/include/asm/stacktrace.h, arch/s390/include/asm/perf_event.h, include/linux/perf_event.h, ...):
   include/linux/ptrace.h:210:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:210:45: sparse:     expected struct task_struct *new_parent
   include/linux/ptrace.h:210:45: sparse:     got struct task_struct [noderef] __rcu *parent
   include/linux/ptrace.h:210:62: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct cred const *ptracer_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   include/linux/ptrace.h:210:62: sparse:     expected struct cred const *ptracer_cred
   include/linux/ptrace.h:210:62: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/fork.c:2458:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2459:59: sparse: sparse: dereference of noderef expression
--
>> kernel/exit.c:84:26: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] new_caba @@     got struct task_struct [noderef] __rcu *caba @@
   kernel/exit.c:84:26: sparse:     expected struct task_struct *[assigned] new_caba
   kernel/exit.c:84:26: sparse:     got struct task_struct [noderef] __rcu *caba
   kernel/exit.c:302:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:302:37: sparse:     expected struct task_struct *tsk
   kernel/exit.c:302:37: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:305:32: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *task @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:305:32: sparse:     expected struct task_struct *task
   kernel/exit.c:305:32: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:306:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *task @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:306:35: sparse:     expected struct task_struct *task
   kernel/exit.c:306:35: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:351:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:351:24: sparse:     expected struct task_struct *parent
   kernel/exit.c:351:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:378:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:378:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:378:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:381:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:381:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:381:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:604:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *reaper @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:604:29: sparse:     expected struct task_struct *reaper
   kernel/exit.c:604:29: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:606:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *reaper @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/exit.c:606:29: sparse:     expected struct task_struct *reaper
   kernel/exit.c:606:29: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/exit.c:930:63: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *const sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/exit.c:930:63: sparse:     expected struct sighand_struct *const sighand
   kernel/exit.c:930:63: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/exit.c:1085:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1085:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1085:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1110:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1110:41: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1110:41: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1199:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1199:25: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1199:25: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1214:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1214:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1214:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1265:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1265:25: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1265:25: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1268:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1268:35: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1268:35: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1274:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/exit.c:1274:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/exit.c:1274:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/exit.c:1455:59: sparse: sparse: incompatible types in comparison expression (different base types):
   kernel/exit.c:1455:59: sparse:    void *
   kernel/exit.c:1455:59: sparse:    struct task_struct [noderef] __rcu *
   kernel/exit.c:1471:25: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu * @@
   kernel/exit.c:1471:25: sparse:     expected struct task_struct *parent
   kernel/exit.c:1471:25: sparse:     got struct task_struct [noderef] __rcu *
   kernel/exit.c: note: in included file:
   include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
   include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
   include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
   include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
   include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
   include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
   include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
   include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
   include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
   include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/exit.c: note: in included file (through include/linux/sched/signal.h, include/linux/rcuwait.h, include/linux/percpu-rwsem.h, ...):
   include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_zombie' - unexpected unlock
   include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_stopped' - unexpected unlock
   include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_continued' - unexpected unlock
   kernel/exit.c: note: in included file:
   include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
   include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
   include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
   include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
   include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/exit.c:1563:9: sparse: sparse: context imbalance in 'do_wait' - wrong count at exit
--
   init/init_task.c:107:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct * @@
   init/init_task.c:107:28: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   init/init_task.c:107:28: sparse:     got struct task_struct *
   init/init_task.c:108:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *parent @@     got struct task_struct * @@
   init/init_task.c:108:28: sparse:     expected struct task_struct [noderef] __rcu *parent
   init/init_task.c:108:28: sparse:     got struct task_struct *
>> init/init_task.c:112:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct * @@
   init/init_task.c:112:28: sparse:     expected struct task_struct [noderef] __rcu *caba
   init/init_task.c:112:28: sparse:     got struct task_struct *
   init/init_task.c:125:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct [noderef] __rcu *sighand @@     got struct sighand_struct * @@
   init/init_task.c:125:28: sparse:     expected struct sighand_struct [noderef] __rcu *sighand
   init/init_task.c:125:28: sparse:     got struct sighand_struct *

vim +2407 kernel/fork.c

  2355	
  2356		/*
  2357		 * Ensure that the cgroup subsystem policies allow the new process to be
  2358		 * forked. It should be noted that the new process's css_set can be changed
  2359		 * between here and cgroup_post_fork() if an organisation operation is in
  2360		 * progress.
  2361		 */
  2362		retval = cgroup_can_fork(p, args);
  2363		if (retval)
  2364			goto bad_fork_put_pidfd;
  2365	
  2366		/*
  2367		 * Now that the cgroups are pinned, re-clone the parent cgroup and put
  2368		 * the new task on the correct runqueue. All this *before* the task
  2369		 * becomes visible.
  2370		 *
  2371		 * This isn't part of ->can_fork() because while the re-cloning is
  2372		 * cgroup specific, it unconditionally needs to place the task on a
  2373		 * runqueue.
  2374		 */
  2375		sched_cgroup_fork(p, args);
  2376	
  2377		/*
  2378		 * From this point on we must avoid any synchronous user-space
  2379		 * communication until we take the tasklist-lock. In particular, we do
  2380		 * not want user-space to be able to predict the process start-time by
  2381		 * stalling fork(2) after we recorded the start_time but before it is
  2382		 * visible to the system.
  2383		 */
  2384	
  2385		p->start_time = ktime_get_ns();
  2386		p->start_boottime = ktime_get_boottime_ns();
  2387	
  2388		/*
  2389		 * Make it visible to the rest of the system, but dont wake it up yet.
  2390		 * Need tasklist lock for parent etc handling!
  2391		 */
  2392		write_lock_irq(&tasklist_lock);
  2393	
  2394		/* CLONE_PARENT re-uses the old parent */
  2395		if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
  2396			p->real_parent = current->real_parent;
  2397			p->parent_exec_id = current->parent_exec_id;
  2398			if (clone_flags & CLONE_THREAD)
  2399				p->exit_signal = -1;
  2400			else
  2401				p->exit_signal = current->group_leader->exit_signal;
  2402		} else {
  2403			p->real_parent = current;
  2404			p->parent_exec_id = current->self_exec_id;
  2405			p->exit_signal = args->exit_signal;
  2406		}
> 2407		p->caba = current;
  2408	
  2409		klp_copy_process(p);
  2410	
  2411		sched_core_fork(p);
  2412	
  2413		spin_lock(&current->sighand->siglock);
  2414	
  2415		/*
  2416		 * Copy seccomp details explicitly here, in case they were changed
  2417		 * before holding sighand lock.
  2418		 */
  2419		copy_seccomp(p);
  2420	
  2421		rv_task_fork(p);
  2422	
  2423		rseq_fork(p, clone_flags);
  2424	
  2425		/* Don't start children in a dying pid namespace */
  2426		if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
  2427			retval = -ENOMEM;
  2428			goto bad_fork_cancel_cgroup;
  2429		}
  2430	
  2431		/* Let kill terminate clone/fork in the middle */
  2432		if (fatal_signal_pending(current)) {
  2433			retval = -EINTR;
  2434			goto bad_fork_cancel_cgroup;
  2435		}
  2436	
  2437		init_task_pid_links(p);
  2438		if (likely(p->pid)) {
  2439			ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
  2440	
  2441			init_task_pid(p, PIDTYPE_PID, pid);
  2442			if (thread_group_leader(p)) {
  2443				init_task_pid(p, PIDTYPE_TGID, pid);
  2444				init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
  2445				init_task_pid(p, PIDTYPE_SID, task_session(current));
  2446	
  2447				if (is_child_reaper(pid)) {
  2448					ns_of_pid(pid)->child_reaper = p;
  2449					p->signal->flags |= SIGNAL_UNKILLABLE;
  2450				}
  2451				p->signal->shared_pending.signal = delayed.signal;
  2452				p->signal->tty = tty_kref_get(current->signal->tty);
  2453				/*
  2454				 * Inherit has_child_subreaper flag under the same
  2455				 * tasklist_lock with adding child to the process tree
  2456				 * for propagate_has_child_subreaper optimization.
  2457				 */
  2458				p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
  2459								 p->real_parent->signal->is_child_subreaper;
  2460				list_add_tail(&p->sibling, &p->real_parent->children);
  2461				list_add_tail(&p->cabd, &p->caba->cabds);
  2462				list_add_tail_rcu(&p->tasks, &init_task.tasks);
  2463				attach_pid(p, PIDTYPE_TGID);
  2464				attach_pid(p, PIDTYPE_PGID);
  2465				attach_pid(p, PIDTYPE_SID);
  2466				__this_cpu_inc(process_counts);
  2467			} else {
  2468				current->signal->nr_threads++;
  2469				atomic_inc(&current->signal->live);
  2470				refcount_inc(&current->signal->sigcnt);
  2471				task_join_group_stop(p);
  2472				list_add_tail_rcu(&p->thread_group,
  2473						  &p->group_leader->thread_group);
  2474				list_add_tail_rcu(&p->thread_node,
  2475						  &p->signal->thread_head);
  2476			}
  2477			attach_pid(p, PIDTYPE_PID);
  2478			nr_threads++;
  2479		}
  2480		total_forks++;
  2481		hlist_del_init(&delayed.node);
  2482		spin_unlock(&current->sighand->siglock);
  2483		syscall_tracepoint_update(p);
  2484		write_unlock_irq(&tasklist_lock);
  2485	
  2486		if (pidfile)
  2487			fd_install(pidfd, pidfile);
  2488	
  2489		proc_fork_connector(p);
  2490		sched_post_fork(p);
  2491		cgroup_post_fork(p, args);
  2492		perf_event_fork(p);
  2493	
  2494		trace_task_newtask(p, clone_flags);
  2495		uprobe_copy_process(p, clone_flags);
  2496	
  2497		copy_oom_score_adj(clone_flags, p);
  2498	
  2499		return p;
  2500	
  2501	bad_fork_cancel_cgroup:
  2502		sched_core_free(p);
  2503		spin_unlock(&current->sighand->siglock);
  2504		write_unlock_irq(&tasklist_lock);
  2505		cgroup_cancel_fork(p, args);
  2506	bad_fork_put_pidfd:
  2507		if (clone_flags & CLONE_PIDFD) {
  2508			fput(pidfile);
  2509			put_unused_fd(pidfd);
  2510		}
  2511	bad_fork_free_pid:
  2512		if (pid != &init_struct_pid)
  2513			free_pid(pid);
  2514	bad_fork_cleanup_thread:
  2515		exit_thread(p);
  2516	bad_fork_cleanup_io:
  2517		if (p->io_context)
  2518			exit_io_context(p);
  2519	bad_fork_cleanup_namespaces:
  2520		exit_task_namespaces(p);
  2521	bad_fork_cleanup_mm:
  2522		if (p->mm) {
  2523			mm_clear_owner(p->mm, p);
  2524			mmput(p->mm);
  2525		}
  2526	bad_fork_cleanup_signal:
  2527		if (!(clone_flags & CLONE_THREAD))
  2528			free_signal_struct(p->signal);
  2529	bad_fork_cleanup_sighand:
  2530		__cleanup_sighand(p->sighand);
  2531	bad_fork_cleanup_fs:
  2532		exit_fs(p); /* blocking */
  2533	bad_fork_cleanup_files:
  2534		exit_files(p); /* blocking */
  2535	bad_fork_cleanup_semundo:
  2536		exit_sem(p);
  2537	bad_fork_cleanup_security:
  2538		security_task_free(p);
  2539	bad_fork_cleanup_audit:
  2540		audit_free(p);
  2541	bad_fork_cleanup_perf:
  2542		perf_event_free_task(p);
  2543	bad_fork_cleanup_policy:
  2544		lockdep_free_task(p);
  2545	#ifdef CONFIG_NUMA
  2546		mpol_put(p->mempolicy);
  2547	#endif
  2548	bad_fork_cleanup_delayacct:
  2549		delayacct_tsk_free(p);
  2550	bad_fork_cleanup_count:
  2551		dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
  2552		exit_creds(p);
  2553	bad_fork_free:
  2554		WRITE_ONCE(p->__state, TASK_DEAD);
  2555		exit_task_stack_account(p);
  2556		put_task_stack(p);
  2557		delayed_free_task(p);
  2558	fork_out:
  2559		spin_lock_irq(&current->sighand->siglock);
  2560		hlist_del_init(&delayed.node);
  2561		spin_unlock_irq(&current->sighand->siglock);
  2562		return ERR_PTR(retval);
  2563	}
  2564	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v4 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
  2022-09-08 21:29   ` kernel test robot
@ 2022-09-08 22:09   ` Pavel Tikhomirov
  2022-09-08 23:51   ` [PATCH v3 " kernel test robot
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Pavel Tikhomirov @ 2022-09-08 22:09 UTC (permalink / raw)
  To: Eric Biederman, Alexander Viro, Christian Brauner, Andrei Vagin,
	linux-kernel
  Cc: Pavel Tikhomirov, Kees Cook, Ingo Molnar, Peter Zijlstra,
	Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
	Valentin Schneider, Andrew Morton, linux-ia64, linux-mm,
	linux-fsdevel, kernel, Alexander Mikhalitsyn

In linux after parent (father) process dies, children processes are
moved (reparented) to a reaper process. Roughly speaking:

1) If father has other yet alive thread, this thread would be a reaper.

2) Else if there is father's ancestor (with no pidns level change in the
middle), which has PR_SET_CHILD_SUBREAPER set, this ancestor would be a
reaper.

3) Else father's pidns init would be a reaper for fathers children.

The problem with this for CRIU is that when CRIU comes to dump processes
it does not know the order in which processes and their resources were
created. And processes can have resources which a) can only be inherited
when we clone processes, b) can only be created by specific processes
and c) are shared between several processes (the example of such a
resource is process session). For such resources CRIU restore would need
to re-invent such order of process creation which at the same time
creates the desired process tree topology and allows to inherit all
resources right.

When process reparenting involves child-sub-reapers one can drastically
mix processes in process tree so that it is not obvious how to restore
everything right.

So this is what we came up with to help CRIU to overcome this problem:

CABA = Closest Alive Born Ancestor
CABD = Closest Alive Born Descendant

We want to put processes in one more tree - CABA tree. This tree is not
affecting reparenting or process creation in any way except for
providing a new information to CRIU so that we can understand from where
the reparented child had reparented, though original father is already
dead and probably a fathers father too, we can still have information
about the process which is still alive and was originally a parent of
process sequence (of already dead processes) which lead to us - CABA.

CC: Eric Biederman <ebiederm@xmission.com>
CC: Kees Cook <keescook@chromium.org>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Ingo Molnar <mingo@redhat.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Juri Lelli <juri.lelli@redhat.com>
CC: Vincent Guittot <vincent.guittot@linaro.org>
CC: Dietmar Eggemann <dietmar.eggemann@arm.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ben Segall <bsegall@google.com>
CC: Mel Gorman <mgorman@suse.de>
CC: Daniel Bristot de Oliveira <bristot@redhat.com>
CC: Valentin Schneider <vschneid@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: linux-ia64@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mm@kvack.org
CC: linux-fsdevel@vger.kernel.org
CC: kernel@openvz.org
CC: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

--
v2: fix unused variables reported-by: kernel test robot <lkp@intel.com>
v3: - on fork set caba to current, so that caba is always a process
      which had initiated our creation, even for CLONE_PARENT case
    - move caba update to a later stage (to __unhash_process), so that
      zombies can be somebodies caba until fully released
v4: fix accidentally setting caba to thread leader when creating threads
---
 arch/ia64/kernel/mca.c |  3 +++
 fs/exec.c              |  1 +
 fs/proc/array.c        | 20 ++++++++++++++++++++
 include/linux/sched.h  |  7 +++++++
 init/init_task.c       |  3 +++
 kernel/exit.c          | 21 +++++++++++++++++++++
 kernel/fork.c          | 11 +++++++++--
 7 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index c62a66710ad6..5e561994cff7 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1793,6 +1793,9 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
 	p->parent = p->real_parent = p->group_leader = p;
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
+	p->caba = p;
+	INIT_LIST_HEAD(&p->cabds);
+	INIT_LIST_HEAD(&p->cabd);
 	strncpy(p->comm, type, sizeof(p->comm)-1);
 }
 
diff --git a/fs/exec.c b/fs/exec.c
index 9a5ca7b82bfc..8caaa03739ab 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1139,6 +1139,7 @@ static int de_thread(struct task_struct *tsk)
 
 		list_replace_rcu(&leader->tasks, &tsk->tasks);
 		list_replace_init(&leader->sibling, &tsk->sibling);
+		list_replace_init(&leader->cabd, &tsk->cabd);
 
 		tsk->group_leader = tsk;
 		leader->group_leader = tsk;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 99fcbfda8e25..5fd70aebd52d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -154,11 +154,28 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	const struct cred *cred;
 	pid_t ppid, tpid = 0, tgid, ngid;
 	unsigned int max_fds = 0;
+#ifdef CONFIG_PID_NS
+	struct task_struct *caba;
+	struct pid *caba_pid;
+	int caba_level = 0;
+	pid_t caba_pids[MAX_PID_NS_LEVEL] = {};
+#endif
 
 	rcu_read_lock();
 	ppid = pid_alive(p) ?
 		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
 
+#ifdef CONFIG_PID_NS
+	caba = rcu_dereference(p->caba);
+	caba_pid = get_task_pid(caba, PIDTYPE_PID);
+	if (caba_pid) {
+		caba_level = caba_pid->level;
+		for (g = ns->level; g <= caba_level; g++)
+			caba_pids[g] = task_pid_nr_ns(caba, caba_pid->numbers[g].ns);
+		put_pid(caba_pid);
+	}
+#endif
+
 	tracer = ptrace_parent(p);
 	if (tracer)
 		tpid = task_pid_nr_ns(tracer, ns);
@@ -217,6 +234,9 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	seq_puts(m, "\nNSsid:");
 	for (g = ns->level; g <= pid->level; g++)
 		seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
+	seq_puts(m, "\nNScaba:");
+	for (g = ns->level; g <= caba_level; g++)
+		seq_put_decimal_ull(m, "\t", caba_pids[g]);
 #endif
 	seq_putc(m, '\n');
 }
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e7b2f8a5c711..b30a2ccf1180 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -975,6 +975,13 @@ struct task_struct {
 	struct list_head		sibling;
 	struct task_struct		*group_leader;
 
+	/* Closest Alive Born Ancestor process: */
+	struct task_struct __rcu	*caba;
+
+	/* Closest Alive Born Descendants list: */
+	struct list_head		cabds;
+	struct list_head		cabd;
+
 	/*
 	 * 'ptraced' is the list of tasks this task is using ptrace() on.
 	 *
diff --git a/init/init_task.c b/init/init_task.c
index ff6c4b9bfe6b..439da3b04dde 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -109,6 +109,9 @@ struct task_struct init_task
 	.children	= LIST_HEAD_INIT(init_task.children),
 	.sibling	= LIST_HEAD_INIT(init_task.sibling),
 	.group_leader	= &init_task,
+	.caba		= &init_task,
+	.cabds		= LIST_HEAD_INIT(init_task.cabds),
+	.cabd		= LIST_HEAD_INIT(init_task.cabd),
 	RCU_POINTER_INITIALIZER(real_cred, &init_cred),
 	RCU_POINTER_INITIALIZER(cred, &init_cred),
 	.comm		= INIT_TASK_COMM,
diff --git a/kernel/exit.c b/kernel/exit.c
index 84021b24f79e..32e4a380861d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -71,9 +71,29 @@
 #include <asm/unistd.h>
 #include <asm/mmu_context.h>
 
+static void forget_caba(struct task_struct *caba)
+{
+	struct task_struct *p, *t, *new_caba;
+
+	if (list_empty(&caba->cabds))
+		return;
+
+	if (!thread_group_leader(caba))
+		new_caba = caba->group_leader;
+	else
+		new_caba = caba->caba;
+
+	list_for_each_entry(p, &caba->cabds, cabd) {
+		for_each_thread(p, t)
+			RCU_INIT_POINTER(t->caba, new_caba);
+	}
+	list_splice_tail_init(&caba->cabds, &new_caba->cabds);
+}
+
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
 	nr_threads--;
+	forget_caba(p);
 	detach_pid(p, PIDTYPE_PID);
 	if (group_dead) {
 		detach_pid(p, PIDTYPE_TGID);
@@ -82,6 +102,7 @@ static void __unhash_process(struct task_struct *p, bool group_dead)
 
 		list_del_rcu(&p->tasks);
 		list_del_init(&p->sibling);
+		list_del_init(&p->cabd);
 		__this_cpu_dec(process_counts);
 	}
 	list_del_rcu(&p->thread_group);
diff --git a/kernel/fork.c b/kernel/fork.c
index 90c85b17bf69..1bd3d815d77f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2139,6 +2139,8 @@ static __latent_entropy struct task_struct *copy_process(
 	p->flags |= PF_FORKNOEXEC;
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
+	INIT_LIST_HEAD(&p->cabds);
+	INIT_LIST_HEAD(&p->cabd);
 	rcu_copy_process(p);
 	p->vfork_done = NULL;
 	spin_lock_init(&p->alloc_lock);
@@ -2393,14 +2395,18 @@ static __latent_entropy struct task_struct *copy_process(
 	if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
 		p->real_parent = current->real_parent;
 		p->parent_exec_id = current->parent_exec_id;
-		if (clone_flags & CLONE_THREAD)
+		if (clone_flags & CLONE_THREAD) {
 			p->exit_signal = -1;
-		else
+			p->caba = p->real_parent;
+		} else {
 			p->exit_signal = current->group_leader->exit_signal;
+			p->caba = current;
+		}
 	} else {
 		p->real_parent = current;
 		p->parent_exec_id = current->self_exec_id;
 		p->exit_signal = args->exit_signal;
+		p->caba = p->real_parent;
 	}
 
 	klp_copy_process(p);
@@ -2455,6 +2461,7 @@ static __latent_entropy struct task_struct *copy_process(
 			p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
 							 p->real_parent->signal->is_child_subreaper;
 			list_add_tail(&p->sibling, &p->real_parent->children);
+			list_add_tail(&p->cabd, &p->caba->cabds);
 			list_add_tail_rcu(&p->tasks, &init_task.tasks);
 			attach_pid(p, PIDTYPE_TGID);
 			attach_pid(p, PIDTYPE_PGID);
-- 
2.37.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 21:29   ` kernel test robot
@ 2022-09-08 22:15     ` Pavel Tikhomirov
  0 siblings, 0 replies; 9+ messages in thread
From: Pavel Tikhomirov @ 2022-09-08 22:15 UTC (permalink / raw)
  To: kernel test robot, Eric Biederman, Alexander Viro,
	Christian Brauner, Andrei Vagin, linux-kernel
  Cc: kbuild-all, Kees Cook, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Daniel Bristot de Oliveira, Valentin Schneider,
	Andrew Morton, Linux Memory Management List, linux-ia64,
	linux-fsdevel, kernel



On 09.09.2022 00:29, kernel test robot wrote:
> Hi Pavel,
> 
> Thank you for the patch! Perhaps something to improve:
> 
> [auto build test WARNING on shuah-kselftest/next]
> [also build test WARNING on kees/for-next/execve tip/sched/core linus/master v6.0-rc4 next-20220908]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
> config: s390-randconfig-s043-20220907 (https://download.01.org/0day-ci/archive/20220909/202209090529.EL54HX2U-lkp@intel.com/config)
> compiler: s390-linux-gcc (GCC) 12.1.0
> reproduce:
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # apt-get install sparse
>          # sparse version: v0.6.4-39-gce1a6720-dirty
>          # https://github.com/intel-lab-lkp/linux/commit/17a897a33137d4f49f99c8be8d619f6f711fccdb
>          git remote add linux-review https://github.com/intel-lab-lkp/linux
>          git fetch --no-tags linux-review Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
>          git checkout 17a897a33137d4f49f99c8be8d619f6f711fccdb
>          # save the config file
>          mkdir build_dir && cp config build_dir/.config
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=s390 SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
> 
> sparse warnings: (new ones prefixed by >>)
>     kernel/fork.c:1307:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct file *[assigned] old_exe_file @@     got struct file [noderef] __rcu *[assigned] __ret @@
>     kernel/fork.c:1307:22: sparse:     expected struct file *[assigned] old_exe_file
>     kernel/fork.c:1307:22: sparse:     got struct file [noderef] __rcu *[assigned] __ret
>     kernel/fork.c:1638:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
>     kernel/fork.c:1638:38: sparse:     expected struct refcount_struct [usertype] *r
>     kernel/fork.c:1638:38: sparse:     got struct refcount_struct [noderef] __rcu *
>     kernel/fork.c:1647:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:1647:31: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:1647:31: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
>     kernel/fork.c:1648:9: sparse:     expected void const *
>     kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
>     kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
>     kernel/fork.c:1648:9: sparse:     expected void const *
>     kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
>     kernel/fork.c:1648:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
>     kernel/fork.c:1648:9: sparse:     expected void const *
>     kernel/fork.c:1648:9: sparse:     got struct k_sigaction [noderef] __rcu *
>     kernel/fork.c:1649:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:1649:33: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:1649:33: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:1742:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct arch_spinlock_t [usertype] *lp @@     got struct arch_spinlock_t [noderef] __rcu * @@
>     kernel/fork.c:1742:9: sparse:     expected struct arch_spinlock_t [usertype] *lp
>     kernel/fork.c:1742:9: sparse:     got struct arch_spinlock_t [noderef] __rcu *
>     kernel/fork.c:2077:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2077:31: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2077:31: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2081:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2081:33: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2081:33: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2403:32: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct * @@
>     kernel/fork.c:2403:32: sparse:     expected struct task_struct [noderef] __rcu *real_parent
>     kernel/fork.c:2403:32: sparse:     got struct task_struct *
>>> kernel/fork.c:2407:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct * @@
>     kernel/fork.c:2407:17: sparse:     expected struct task_struct [noderef] __rcu *caba
>     kernel/fork.c:2407:17: sparse:     got struct task_struct *
>     kernel/fork.c:2413:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2413:27: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2413:27: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2460:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
>     kernel/fork.c:2460:54: sparse:     expected struct list_head *head
>     kernel/fork.c:2460:54: sparse:     got struct list_head [noderef] __rcu *
>     kernel/fork.c:2461:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
>     kernel/fork.c:2461:51: sparse:     expected struct list_head *head
>     kernel/fork.c:2461:51: sparse:     got struct list_head [noderef] __rcu *
>     kernel/fork.c:2482:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2482:29: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2482:29: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2503:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2503:29: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2503:29: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2530:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
>     kernel/fork.c:2530:28: sparse:     expected struct sighand_struct *sighand
>     kernel/fork.c:2530:28: sparse:     got struct sighand_struct [noderef] __rcu *sighand
>     kernel/fork.c:2559:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2559:31: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2559:31: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2561:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/fork.c:2561:33: sparse:     expected struct spinlock [usertype] *lock
>     kernel/fork.c:2561:33: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/fork.c:2997:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] parent @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/fork.c:2997:24: sparse:     expected struct task_struct *[assigned] parent
>     kernel/fork.c:2997:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/fork.c:3078:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct const [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
>     kernel/fork.c:3078:43: sparse:     expected struct refcount_struct const [usertype] *r
>     kernel/fork.c:3078:43: sparse:     got struct refcount_struct [noderef] __rcu *
>     kernel/fork.c:2122:22: sparse: sparse: dereference of noderef expression
>     kernel/fork.c: note: in included file (through arch/s390/include/asm/stacktrace.h, arch/s390/include/asm/perf_event.h, include/linux/perf_event.h, ...):
>     include/linux/ptrace.h:210:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *parent @@
>     include/linux/ptrace.h:210:45: sparse:     expected struct task_struct *new_parent
>     include/linux/ptrace.h:210:45: sparse:     got struct task_struct [noderef] __rcu *parent
>     include/linux/ptrace.h:210:62: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct cred const *ptracer_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
>     include/linux/ptrace.h:210:62: sparse:     expected struct cred const *ptracer_cred
>     include/linux/ptrace.h:210:62: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
>     kernel/fork.c:2458:59: sparse: sparse: dereference of noderef expression
>     kernel/fork.c:2459:59: sparse: sparse: dereference of noderef expression
> --
>>> kernel/exit.c:84:26: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] new_caba @@     got struct task_struct [noderef] __rcu *caba @@
>     kernel/exit.c:84:26: sparse:     expected struct task_struct *[assigned] new_caba
>     kernel/exit.c:84:26: sparse:     got struct task_struct [noderef] __rcu *caba
>     kernel/exit.c:302:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:302:37: sparse:     expected struct task_struct *tsk
>     kernel/exit.c:302:37: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:305:32: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *task @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:305:32: sparse:     expected struct task_struct *task
>     kernel/exit.c:305:32: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:306:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *task @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:306:35: sparse:     expected struct task_struct *task
>     kernel/exit.c:306:35: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:351:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:351:24: sparse:     expected struct task_struct *parent
>     kernel/exit.c:351:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:378:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:378:27: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:378:27: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:381:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:381:29: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:381:29: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:604:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *reaper @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:604:29: sparse:     expected struct task_struct *reaper
>     kernel/exit.c:604:29: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:606:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *reaper @@     got struct task_struct [noderef] __rcu *real_parent @@
>     kernel/exit.c:606:29: sparse:     expected struct task_struct *reaper
>     kernel/exit.c:606:29: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     kernel/exit.c:930:63: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct *const sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
>     kernel/exit.c:930:63: sparse:     expected struct sighand_struct *const sighand
>     kernel/exit.c:930:63: sparse:     got struct sighand_struct [noderef] __rcu *sighand
>     kernel/exit.c:1085:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1085:39: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1085:39: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1110:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1110:41: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1110:41: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1199:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1199:25: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1199:25: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1214:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1214:27: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1214:27: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1265:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1265:25: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1265:25: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1268:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1268:35: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1268:35: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1274:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
>     kernel/exit.c:1274:27: sparse:     expected struct spinlock [usertype] *lock
>     kernel/exit.c:1274:27: sparse:     got struct spinlock [noderef] __rcu *
>     kernel/exit.c:1455:59: sparse: sparse: incompatible types in comparison expression (different base types):
>     kernel/exit.c:1455:59: sparse:    void *
>     kernel/exit.c:1455:59: sparse:    struct task_struct [noderef] __rcu *
>     kernel/exit.c:1471:25: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu * @@
>     kernel/exit.c:1471:25: sparse:     expected struct task_struct *parent
>     kernel/exit.c:1471:25: sparse:     got struct task_struct [noderef] __rcu *
>     kernel/exit.c: note: in included file:
>     include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
>     include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
>     include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
>     include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
>     include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
>     include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
>     include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
>     include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
>     include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
>     include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
>     kernel/exit.c: note: in included file (through include/linux/sched/signal.h, include/linux/rcuwait.h, include/linux/percpu-rwsem.h, ...):
>     include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_zombie' - unexpected unlock
>     include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_stopped' - unexpected unlock
>     include/linux/sched/task.h:110:21: sparse: sparse: context imbalance in 'wait_task_continued' - unexpected unlock
>     kernel/exit.c: note: in included file:
>     include/linux/ptrace.h:92:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
>     include/linux/ptrace.h:92:40: sparse:     expected struct task_struct *p1
>     include/linux/ptrace.h:92:40: sparse:     got struct task_struct [noderef] __rcu *real_parent
>     include/linux/ptrace.h:92:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
>     include/linux/ptrace.h:92:60: sparse:     expected struct task_struct *p2
>     include/linux/ptrace.h:92:60: sparse:     got struct task_struct [noderef] __rcu *parent
>     kernel/exit.c:1563:9: sparse: sparse: context imbalance in 'do_wait' - wrong count at exit
> --
>     init/init_task.c:107:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct * @@
>     init/init_task.c:107:28: sparse:     expected struct task_struct [noderef] __rcu *real_parent
>     init/init_task.c:107:28: sparse:     got struct task_struct *
>     init/init_task.c:108:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *parent @@     got struct task_struct * @@
>     init/init_task.c:108:28: sparse:     expected struct task_struct [noderef] __rcu *parent
>     init/init_task.c:108:28: sparse:     got struct task_struct *
>>> init/init_task.c:112:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct * @@
>     init/init_task.c:112:28: sparse:     expected struct task_struct [noderef] __rcu *caba
>     init/init_task.c:112:28: sparse:     got struct task_struct *
>     init/init_task.c:125:28: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sighand_struct [noderef] __rcu *sighand @@     got struct sighand_struct * @@
>     init/init_task.c:125:28: sparse:     expected struct sighand_struct [noderef] __rcu *sighand
>     init/init_task.c:125:28: sparse:     got struct sighand_struct *
> 
> vim +2407 kernel/fork.c
> 
>    2355	
>    2356		/*
>    2357		 * Ensure that the cgroup subsystem policies allow the new process to be
>    2358		 * forked. It should be noted that the new process's css_set can be changed
>    2359		 * between here and cgroup_post_fork() if an organisation operation is in
>    2360		 * progress.
>    2361		 */
>    2362		retval = cgroup_can_fork(p, args);
>    2363		if (retval)
>    2364			goto bad_fork_put_pidfd;
>    2365	
>    2366		/*
>    2367		 * Now that the cgroups are pinned, re-clone the parent cgroup and put
>    2368		 * the new task on the correct runqueue. All this *before* the task
>    2369		 * becomes visible.
>    2370		 *
>    2371		 * This isn't part of ->can_fork() because while the re-cloning is
>    2372		 * cgroup specific, it unconditionally needs to place the task on a
>    2373		 * runqueue.
>    2374		 */
>    2375		sched_cgroup_fork(p, args);
>    2376	
>    2377		/*
>    2378		 * From this point on we must avoid any synchronous user-space
>    2379		 * communication until we take the tasklist-lock. In particular, we do
>    2380		 * not want user-space to be able to predict the process start-time by
>    2381		 * stalling fork(2) after we recorded the start_time but before it is
>    2382		 * visible to the system.
>    2383		 */
>    2384	
>    2385		p->start_time = ktime_get_ns();
>    2386		p->start_boottime = ktime_get_boottime_ns();
>    2387	
>    2388		/*
>    2389		 * Make it visible to the rest of the system, but dont wake it up yet.
>    2390		 * Need tasklist lock for parent etc handling!
>    2391		 */
>    2392		write_lock_irq(&tasklist_lock);
>    2393	
>    2394		/* CLONE_PARENT re-uses the old parent */
>    2395		if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
>    2396			p->real_parent = current->real_parent;
>    2397			p->parent_exec_id = current->parent_exec_id;
>    2398			if (clone_flags & CLONE_THREAD)
>    2399				p->exit_signal = -1;
>    2400			else
>    2401				p->exit_signal = current->group_leader->exit_signal;
>    2402		} else {
>    2403			p->real_parent = current;
>    2404			p->parent_exec_id = current->self_exec_id;
>    2405			p->exit_signal = args->exit_signal;
>    2406		}
>> 2407		p->caba = current;

Not sure how to fix this error, we set real_parent to current just 
several lines above, but as I want to set caba to current in 
CLONE_PARENT case to see actual parent after CLONE_PARENT calls, and I 
can't take it from real_parent which is different in this case.

Note that I've updated this patch to v4, as for threads creation caba = 
current was not a desired behaviour.

>    2408	
>    2409		klp_copy_process(p);
>    2410	
>    2411		sched_core_fork(p);
>    2412	
>    2413		spin_lock(&current->sighand->siglock);
>    2414	
>    2415		/*
>    2416		 * Copy seccomp details explicitly here, in case they were changed
>    2417		 * before holding sighand lock.
>    2418		 */
>    2419		copy_seccomp(p);
>    2420	
>    2421		rv_task_fork(p);
>    2422	
>    2423		rseq_fork(p, clone_flags);
>    2424	
>    2425		/* Don't start children in a dying pid namespace */
>    2426		if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
>    2427			retval = -ENOMEM;
>    2428			goto bad_fork_cancel_cgroup;
>    2429		}
>    2430	
>    2431		/* Let kill terminate clone/fork in the middle */
>    2432		if (fatal_signal_pending(current)) {
>    2433			retval = -EINTR;
>    2434			goto bad_fork_cancel_cgroup;
>    2435		}
>    2436	
>    2437		init_task_pid_links(p);
>    2438		if (likely(p->pid)) {
>    2439			ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
>    2440	
>    2441			init_task_pid(p, PIDTYPE_PID, pid);
>    2442			if (thread_group_leader(p)) {
>    2443				init_task_pid(p, PIDTYPE_TGID, pid);
>    2444				init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
>    2445				init_task_pid(p, PIDTYPE_SID, task_session(current));
>    2446	
>    2447				if (is_child_reaper(pid)) {
>    2448					ns_of_pid(pid)->child_reaper = p;
>    2449					p->signal->flags |= SIGNAL_UNKILLABLE;
>    2450				}
>    2451				p->signal->shared_pending.signal = delayed.signal;
>    2452				p->signal->tty = tty_kref_get(current->signal->tty);
>    2453				/*
>    2454				 * Inherit has_child_subreaper flag under the same
>    2455				 * tasklist_lock with adding child to the process tree
>    2456				 * for propagate_has_child_subreaper optimization.
>    2457				 */
>    2458				p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
>    2459								 p->real_parent->signal->is_child_subreaper;
>    2460				list_add_tail(&p->sibling, &p->real_parent->children);
>    2461				list_add_tail(&p->cabd, &p->caba->cabds);
>    2462				list_add_tail_rcu(&p->tasks, &init_task.tasks);
>    2463				attach_pid(p, PIDTYPE_TGID);
>    2464				attach_pid(p, PIDTYPE_PGID);
>    2465				attach_pid(p, PIDTYPE_SID);
>    2466				__this_cpu_inc(process_counts);
>    2467			} else {
>    2468				current->signal->nr_threads++;
>    2469				atomic_inc(&current->signal->live);
>    2470				refcount_inc(&current->signal->sigcnt);
>    2471				task_join_group_stop(p);
>    2472				list_add_tail_rcu(&p->thread_group,
>    2473						  &p->group_leader->thread_group);
>    2474				list_add_tail_rcu(&p->thread_node,
>    2475						  &p->signal->thread_head);
>    2476			}
>    2477			attach_pid(p, PIDTYPE_PID);
>    2478			nr_threads++;
>    2479		}
>    2480		total_forks++;
>    2481		hlist_del_init(&delayed.node);
>    2482		spin_unlock(&current->sighand->siglock);
>    2483		syscall_tracepoint_update(p);
>    2484		write_unlock_irq(&tasklist_lock);
>    2485	
>    2486		if (pidfile)
>    2487			fd_install(pidfd, pidfile);
>    2488	
>    2489		proc_fork_connector(p);
>    2490		sched_post_fork(p);
>    2491		cgroup_post_fork(p, args);
>    2492		perf_event_fork(p);
>    2493	
>    2494		trace_task_newtask(p, clone_flags);
>    2495		uprobe_copy_process(p, clone_flags);
>    2496	
>    2497		copy_oom_score_adj(clone_flags, p);
>    2498	
>    2499		return p;
>    2500	
>    2501	bad_fork_cancel_cgroup:
>    2502		sched_core_free(p);
>    2503		spin_unlock(&current->sighand->siglock);
>    2504		write_unlock_irq(&tasklist_lock);
>    2505		cgroup_cancel_fork(p, args);
>    2506	bad_fork_put_pidfd:
>    2507		if (clone_flags & CLONE_PIDFD) {
>    2508			fput(pidfile);
>    2509			put_unused_fd(pidfd);
>    2510		}
>    2511	bad_fork_free_pid:
>    2512		if (pid != &init_struct_pid)
>    2513			free_pid(pid);
>    2514	bad_fork_cleanup_thread:
>    2515		exit_thread(p);
>    2516	bad_fork_cleanup_io:
>    2517		if (p->io_context)
>    2518			exit_io_context(p);
>    2519	bad_fork_cleanup_namespaces:
>    2520		exit_task_namespaces(p);
>    2521	bad_fork_cleanup_mm:
>    2522		if (p->mm) {
>    2523			mm_clear_owner(p->mm, p);
>    2524			mmput(p->mm);
>    2525		}
>    2526	bad_fork_cleanup_signal:
>    2527		if (!(clone_flags & CLONE_THREAD))
>    2528			free_signal_struct(p->signal);
>    2529	bad_fork_cleanup_sighand:
>    2530		__cleanup_sighand(p->sighand);
>    2531	bad_fork_cleanup_fs:
>    2532		exit_fs(p); /* blocking */
>    2533	bad_fork_cleanup_files:
>    2534		exit_files(p); /* blocking */
>    2535	bad_fork_cleanup_semundo:
>    2536		exit_sem(p);
>    2537	bad_fork_cleanup_security:
>    2538		security_task_free(p);
>    2539	bad_fork_cleanup_audit:
>    2540		audit_free(p);
>    2541	bad_fork_cleanup_perf:
>    2542		perf_event_free_task(p);
>    2543	bad_fork_cleanup_policy:
>    2544		lockdep_free_task(p);
>    2545	#ifdef CONFIG_NUMA
>    2546		mpol_put(p->mempolicy);
>    2547	#endif
>    2548	bad_fork_cleanup_delayacct:
>    2549		delayacct_tsk_free(p);
>    2550	bad_fork_cleanup_count:
>    2551		dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
>    2552		exit_creds(p);
>    2553	bad_fork_free:
>    2554		WRITE_ONCE(p->__state, TASK_DEAD);
>    2555		exit_task_stack_account(p);
>    2556		put_task_stack(p);
>    2557		delayed_free_task(p);
>    2558	fork_out:
>    2559		spin_lock_irq(&current->sighand->siglock);
>    2560		hlist_del_init(&delayed.node);
>    2561		spin_unlock_irq(&current->sighand->siglock);
>    2562		return ERR_PTR(retval);
>    2563	}
>    2564	
> 

-- 
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
  2022-09-08 21:29   ` kernel test robot
  2022-09-08 22:09   ` [PATCH v4 " Pavel Tikhomirov
@ 2022-09-08 23:51   ` kernel test robot
  2022-09-09  1:02   ` kernel test robot
  2022-09-11 19:27   ` kernel test robot
  4 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-09-08 23:51 UTC (permalink / raw)
  To: Pavel Tikhomirov, Eric Biederman, Alexander Viro,
	Christian Brauner, Andrei Vagin, linux-kernel
  Cc: kbuild-all, Pavel Tikhomirov, Kees Cook, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman,
	Daniel Bristot de Oliveira, Valentin Schneider, Andrew Morton,
	Linux Memory Management List, linux-ia64, linux-fsdevel, kernel

Hi Pavel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on kees/for-next/execve tip/sched/core linus/master v6.0-rc4 next-20220908]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
config: loongarch-randconfig-s031-20220907 (https://download.01.org/0day-ci/archive/20220909/202209090715.tbbHbdhr-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/17a897a33137d4f49f99c8be8d619f6f711fccdb
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
        git checkout 17a897a33137d4f49f99c8be8d619f6f711fccdb
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=loongarch SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

sparse warnings: (new ones prefixed by >>)
   kernel/fork.c:1098:19: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *owner @@     got struct task_struct *p @@
   kernel/fork.c:1098:19: sparse:     expected struct task_struct [noderef] __rcu *owner
   kernel/fork.c:1098:19: sparse:     got struct task_struct *p
   kernel/fork.c:1307:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct file *[assigned] old_exe_file @@     got struct file [noderef] __rcu *[assigned] __res @@
   kernel/fork.c:1307:22: sparse:     expected struct file *[assigned] old_exe_file
   kernel/fork.c:1307:22: sparse:     got struct file [noderef] __rcu *[assigned] __res
   kernel/fork.c:1638:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:1638:38: sparse:     expected struct refcount_struct [usertype] *r
   kernel/fork.c:1638:38: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1647:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1647:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1647:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:1648:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1648:36: sparse:     expected void const *
   kernel/fork.c:1648:36: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1649:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1649:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1649:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2077:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2077:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2077:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2081:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2081:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2081:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2403:32: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct *task @@
   kernel/fork.c:2403:32: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:2403:32: sparse:     got struct task_struct *task
>> kernel/fork.c:2407:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct *task @@
   kernel/fork.c:2407:17: sparse:     expected struct task_struct [noderef] __rcu *caba
   kernel/fork.c:2407:17: sparse:     got struct task_struct *task
   kernel/fork.c:2413:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2413:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2413:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2460:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2460:54: sparse:     expected struct list_head *head
   kernel/fork.c:2460:54: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2461:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2461:51: sparse:     expected struct list_head *head
   kernel/fork.c:2461:51: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2482:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2482:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2482:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2503:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2503:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2503:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2530:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/fork.c:2530:28: sparse:     expected struct sighand_struct *sighand
   kernel/fork.c:2530:28: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/fork.c:2559:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2559:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2559:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2561:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2561:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2561:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2997:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/fork.c:2997:24: sparse:     expected struct task_struct *[assigned] parent
   kernel/fork.c:2997:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:3078:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct const [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:3078:43: sparse:     expected struct refcount_struct const [usertype] *r
   kernel/fork.c:3078:43: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:2122:22: sparse: sparse: dereference of noderef expression
   kernel/fork.c: note: in included file (through include/uapi/asm-generic/bpf_perf_event.h, arch/loongarch/include/generated/uapi/asm/bpf_perf_event.h, ...):
   include/linux/ptrace.h:210:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:210:45: sparse:     expected struct task_struct *new_parent
   include/linux/ptrace.h:210:45: sparse:     got struct task_struct [noderef] __rcu *parent
   include/linux/ptrace.h:210:62: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct cred const *ptracer_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   include/linux/ptrace.h:210:62: sparse:     expected struct cred const *ptracer_cred
   include/linux/ptrace.h:210:62: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/fork.c:2458:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2459:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:1090:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/fork.c:1090:23: sparse:    struct task_struct [noderef] __rcu *
   kernel/fork.c:1090:23: sparse:    struct task_struct *

vim +2407 kernel/fork.c

  2355	
  2356		/*
  2357		 * Ensure that the cgroup subsystem policies allow the new process to be
  2358		 * forked. It should be noted that the new process's css_set can be changed
  2359		 * between here and cgroup_post_fork() if an organisation operation is in
  2360		 * progress.
  2361		 */
  2362		retval = cgroup_can_fork(p, args);
  2363		if (retval)
  2364			goto bad_fork_put_pidfd;
  2365	
  2366		/*
  2367		 * Now that the cgroups are pinned, re-clone the parent cgroup and put
  2368		 * the new task on the correct runqueue. All this *before* the task
  2369		 * becomes visible.
  2370		 *
  2371		 * This isn't part of ->can_fork() because while the re-cloning is
  2372		 * cgroup specific, it unconditionally needs to place the task on a
  2373		 * runqueue.
  2374		 */
  2375		sched_cgroup_fork(p, args);
  2376	
  2377		/*
  2378		 * From this point on we must avoid any synchronous user-space
  2379		 * communication until we take the tasklist-lock. In particular, we do
  2380		 * not want user-space to be able to predict the process start-time by
  2381		 * stalling fork(2) after we recorded the start_time but before it is
  2382		 * visible to the system.
  2383		 */
  2384	
  2385		p->start_time = ktime_get_ns();
  2386		p->start_boottime = ktime_get_boottime_ns();
  2387	
  2388		/*
  2389		 * Make it visible to the rest of the system, but dont wake it up yet.
  2390		 * Need tasklist lock for parent etc handling!
  2391		 */
  2392		write_lock_irq(&tasklist_lock);
  2393	
  2394		/* CLONE_PARENT re-uses the old parent */
  2395		if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
  2396			p->real_parent = current->real_parent;
  2397			p->parent_exec_id = current->parent_exec_id;
  2398			if (clone_flags & CLONE_THREAD)
  2399				p->exit_signal = -1;
  2400			else
  2401				p->exit_signal = current->group_leader->exit_signal;
  2402		} else {
  2403			p->real_parent = current;
  2404			p->parent_exec_id = current->self_exec_id;
  2405			p->exit_signal = args->exit_signal;
  2406		}
> 2407		p->caba = current;
  2408	
  2409		klp_copy_process(p);
  2410	
  2411		sched_core_fork(p);
  2412	
  2413		spin_lock(&current->sighand->siglock);
  2414	
  2415		/*
  2416		 * Copy seccomp details explicitly here, in case they were changed
  2417		 * before holding sighand lock.
  2418		 */
  2419		copy_seccomp(p);
  2420	
  2421		rv_task_fork(p);
  2422	
  2423		rseq_fork(p, clone_flags);
  2424	
  2425		/* Don't start children in a dying pid namespace */
  2426		if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
  2427			retval = -ENOMEM;
  2428			goto bad_fork_cancel_cgroup;
  2429		}
  2430	
  2431		/* Let kill terminate clone/fork in the middle */
  2432		if (fatal_signal_pending(current)) {
  2433			retval = -EINTR;
  2434			goto bad_fork_cancel_cgroup;
  2435		}
  2436	
  2437		init_task_pid_links(p);
  2438		if (likely(p->pid)) {
  2439			ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
  2440	
  2441			init_task_pid(p, PIDTYPE_PID, pid);
  2442			if (thread_group_leader(p)) {
  2443				init_task_pid(p, PIDTYPE_TGID, pid);
  2444				init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
  2445				init_task_pid(p, PIDTYPE_SID, task_session(current));
  2446	
  2447				if (is_child_reaper(pid)) {
  2448					ns_of_pid(pid)->child_reaper = p;
  2449					p->signal->flags |= SIGNAL_UNKILLABLE;
  2450				}
  2451				p->signal->shared_pending.signal = delayed.signal;
  2452				p->signal->tty = tty_kref_get(current->signal->tty);
  2453				/*
  2454				 * Inherit has_child_subreaper flag under the same
  2455				 * tasklist_lock with adding child to the process tree
  2456				 * for propagate_has_child_subreaper optimization.
  2457				 */
  2458				p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
  2459								 p->real_parent->signal->is_child_subreaper;
  2460				list_add_tail(&p->sibling, &p->real_parent->children);
  2461				list_add_tail(&p->cabd, &p->caba->cabds);
  2462				list_add_tail_rcu(&p->tasks, &init_task.tasks);
  2463				attach_pid(p, PIDTYPE_TGID);
  2464				attach_pid(p, PIDTYPE_PGID);
  2465				attach_pid(p, PIDTYPE_SID);
  2466				__this_cpu_inc(process_counts);
  2467			} else {
  2468				current->signal->nr_threads++;
  2469				atomic_inc(&current->signal->live);
  2470				refcount_inc(&current->signal->sigcnt);
  2471				task_join_group_stop(p);
  2472				list_add_tail_rcu(&p->thread_group,
  2473						  &p->group_leader->thread_group);
  2474				list_add_tail_rcu(&p->thread_node,
  2475						  &p->signal->thread_head);
  2476			}
  2477			attach_pid(p, PIDTYPE_PID);
  2478			nr_threads++;
  2479		}
  2480		total_forks++;
  2481		hlist_del_init(&delayed.node);
  2482		spin_unlock(&current->sighand->siglock);
  2483		syscall_tracepoint_update(p);
  2484		write_unlock_irq(&tasklist_lock);
  2485	
  2486		if (pidfile)
  2487			fd_install(pidfd, pidfile);
  2488	
  2489		proc_fork_connector(p);
  2490		sched_post_fork(p);
  2491		cgroup_post_fork(p, args);
  2492		perf_event_fork(p);
  2493	
  2494		trace_task_newtask(p, clone_flags);
  2495		uprobe_copy_process(p, clone_flags);
  2496	
  2497		copy_oom_score_adj(clone_flags, p);
  2498	
  2499		return p;
  2500	
  2501	bad_fork_cancel_cgroup:
  2502		sched_core_free(p);
  2503		spin_unlock(&current->sighand->siglock);
  2504		write_unlock_irq(&tasklist_lock);
  2505		cgroup_cancel_fork(p, args);
  2506	bad_fork_put_pidfd:
  2507		if (clone_flags & CLONE_PIDFD) {
  2508			fput(pidfile);
  2509			put_unused_fd(pidfd);
  2510		}
  2511	bad_fork_free_pid:
  2512		if (pid != &init_struct_pid)
  2513			free_pid(pid);
  2514	bad_fork_cleanup_thread:
  2515		exit_thread(p);
  2516	bad_fork_cleanup_io:
  2517		if (p->io_context)
  2518			exit_io_context(p);
  2519	bad_fork_cleanup_namespaces:
  2520		exit_task_namespaces(p);
  2521	bad_fork_cleanup_mm:
  2522		if (p->mm) {
  2523			mm_clear_owner(p->mm, p);
  2524			mmput(p->mm);
  2525		}
  2526	bad_fork_cleanup_signal:
  2527		if (!(clone_flags & CLONE_THREAD))
  2528			free_signal_struct(p->signal);
  2529	bad_fork_cleanup_sighand:
  2530		__cleanup_sighand(p->sighand);
  2531	bad_fork_cleanup_fs:
  2532		exit_fs(p); /* blocking */
  2533	bad_fork_cleanup_files:
  2534		exit_files(p); /* blocking */
  2535	bad_fork_cleanup_semundo:
  2536		exit_sem(p);
  2537	bad_fork_cleanup_security:
  2538		security_task_free(p);
  2539	bad_fork_cleanup_audit:
  2540		audit_free(p);
  2541	bad_fork_cleanup_perf:
  2542		perf_event_free_task(p);
  2543	bad_fork_cleanup_policy:
  2544		lockdep_free_task(p);
  2545	#ifdef CONFIG_NUMA
  2546		mpol_put(p->mempolicy);
  2547	#endif
  2548	bad_fork_cleanup_delayacct:
  2549		delayacct_tsk_free(p);
  2550	bad_fork_cleanup_count:
  2551		dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
  2552		exit_creds(p);
  2553	bad_fork_free:
  2554		WRITE_ONCE(p->__state, TASK_DEAD);
  2555		exit_task_stack_account(p);
  2556		put_task_stack(p);
  2557		delayed_free_task(p);
  2558	fork_out:
  2559		spin_lock_irq(&current->sighand->siglock);
  2560		hlist_del_init(&delayed.node);
  2561		spin_unlock_irq(&current->sighand->siglock);
  2562		return ERR_PTR(retval);
  2563	}
  2564	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
                     ` (2 preceding siblings ...)
  2022-09-08 23:51   ` [PATCH v3 " kernel test robot
@ 2022-09-09  1:02   ` kernel test robot
  2022-09-11 19:27   ` kernel test robot
  4 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-09-09  1:02 UTC (permalink / raw)
  To: Pavel Tikhomirov, Eric Biederman, Alexander Viro,
	Christian Brauner, Andrei Vagin, linux-kernel
  Cc: kbuild-all, Pavel Tikhomirov, Kees Cook, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman,
	Daniel Bristot de Oliveira, Valentin Schneider, Andrew Morton,
	Linux Memory Management List, linux-ia64, linux-fsdevel, kernel

Hi Pavel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on kees/for-next/execve tip/sched/core linus/master v6.0-rc4 next-20220908]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
config: microblaze-randconfig-s053-20220907 (https://download.01.org/0day-ci/archive/20220909/202209090830.H0tKErRt-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/17a897a33137d4f49f99c8be8d619f6f711fccdb
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
        git checkout 17a897a33137d4f49f99c8be8d619f6f711fccdb
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

sparse warnings: (new ones prefixed by >>)
   kernel/fork.c:1307:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct file *[assigned] old_exe_file @@     got struct file [noderef] __rcu * @@
   kernel/fork.c:1307:22: sparse:     expected struct file *[assigned] old_exe_file
   kernel/fork.c:1307:22: sparse:     got struct file [noderef] __rcu *
   kernel/fork.c:1638:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:1638:38: sparse:     expected struct refcount_struct [usertype] *r
   kernel/fork.c:1638:38: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1647:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1647:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1647:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:1648:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const * @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1648:36: sparse:     expected void const *
   kernel/fork.c:1648:36: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1649:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1649:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1649:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2077:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2077:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2077:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2081:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2081:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2081:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2403:32: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct *register [addressable] [toplevel] current @@
   kernel/fork.c:2403:32: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:2403:32: sparse:     got struct task_struct *register [addressable] [toplevel] current
>> kernel/fork.c:2407:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct *register [addressable] [toplevel] current @@
   kernel/fork.c:2407:17: sparse:     expected struct task_struct [noderef] __rcu *caba
   kernel/fork.c:2407:17: sparse:     got struct task_struct *register [addressable] [toplevel] current
   kernel/fork.c:2413:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2413:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2413:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2460:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2460:54: sparse:     expected struct list_head *head
   kernel/fork.c:2460:54: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2461:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2461:51: sparse:     expected struct list_head *head
   kernel/fork.c:2461:51: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2482:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2482:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2482:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2503:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2503:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2503:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2530:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/fork.c:2530:28: sparse:     expected struct sighand_struct *sighand
   kernel/fork.c:2530:28: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/fork.c:2559:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2559:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2559:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2561:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2561:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2561:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2997:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/fork.c:2997:24: sparse:     expected struct task_struct *[assigned] parent
   kernel/fork.c:2997:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:3078:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct const [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:3078:43: sparse:     expected struct refcount_struct const [usertype] *r
   kernel/fork.c:3078:43: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1742:9: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2122:22: sparse: sparse: dereference of noderef expression
   kernel/fork.c: note: in included file (through include/uapi/asm-generic/bpf_perf_event.h, arch/microblaze/include/generated/uapi/asm/bpf_perf_event.h, ...):
   include/linux/ptrace.h:210:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:210:45: sparse:     expected struct task_struct *new_parent
   include/linux/ptrace.h:210:45: sparse:     got struct task_struct [noderef] __rcu *parent
   include/linux/ptrace.h:210:62: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct cred const *ptracer_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   include/linux/ptrace.h:210:62: sparse:     expected struct cred const *ptracer_cred
   include/linux/ptrace.h:210:62: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/fork.c:2458:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2459:59: sparse: sparse: dereference of noderef expression

vim +2407 kernel/fork.c

  2355	
  2356		/*
  2357		 * Ensure that the cgroup subsystem policies allow the new process to be
  2358		 * forked. It should be noted that the new process's css_set can be changed
  2359		 * between here and cgroup_post_fork() if an organisation operation is in
  2360		 * progress.
  2361		 */
  2362		retval = cgroup_can_fork(p, args);
  2363		if (retval)
  2364			goto bad_fork_put_pidfd;
  2365	
  2366		/*
  2367		 * Now that the cgroups are pinned, re-clone the parent cgroup and put
  2368		 * the new task on the correct runqueue. All this *before* the task
  2369		 * becomes visible.
  2370		 *
  2371		 * This isn't part of ->can_fork() because while the re-cloning is
  2372		 * cgroup specific, it unconditionally needs to place the task on a
  2373		 * runqueue.
  2374		 */
  2375		sched_cgroup_fork(p, args);
  2376	
  2377		/*
  2378		 * From this point on we must avoid any synchronous user-space
  2379		 * communication until we take the tasklist-lock. In particular, we do
  2380		 * not want user-space to be able to predict the process start-time by
  2381		 * stalling fork(2) after we recorded the start_time but before it is
  2382		 * visible to the system.
  2383		 */
  2384	
  2385		p->start_time = ktime_get_ns();
  2386		p->start_boottime = ktime_get_boottime_ns();
  2387	
  2388		/*
  2389		 * Make it visible to the rest of the system, but dont wake it up yet.
  2390		 * Need tasklist lock for parent etc handling!
  2391		 */
  2392		write_lock_irq(&tasklist_lock);
  2393	
  2394		/* CLONE_PARENT re-uses the old parent */
  2395		if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
  2396			p->real_parent = current->real_parent;
  2397			p->parent_exec_id = current->parent_exec_id;
  2398			if (clone_flags & CLONE_THREAD)
  2399				p->exit_signal = -1;
  2400			else
  2401				p->exit_signal = current->group_leader->exit_signal;
  2402		} else {
  2403			p->real_parent = current;
  2404			p->parent_exec_id = current->self_exec_id;
  2405			p->exit_signal = args->exit_signal;
  2406		}
> 2407		p->caba = current;
  2408	
  2409		klp_copy_process(p);
  2410	
  2411		sched_core_fork(p);
  2412	
  2413		spin_lock(&current->sighand->siglock);
  2414	
  2415		/*
  2416		 * Copy seccomp details explicitly here, in case they were changed
  2417		 * before holding sighand lock.
  2418		 */
  2419		copy_seccomp(p);
  2420	
  2421		rv_task_fork(p);
  2422	
  2423		rseq_fork(p, clone_flags);
  2424	
  2425		/* Don't start children in a dying pid namespace */
  2426		if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
  2427			retval = -ENOMEM;
  2428			goto bad_fork_cancel_cgroup;
  2429		}
  2430	
  2431		/* Let kill terminate clone/fork in the middle */
  2432		if (fatal_signal_pending(current)) {
  2433			retval = -EINTR;
  2434			goto bad_fork_cancel_cgroup;
  2435		}
  2436	
  2437		init_task_pid_links(p);
  2438		if (likely(p->pid)) {
  2439			ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
  2440	
  2441			init_task_pid(p, PIDTYPE_PID, pid);
  2442			if (thread_group_leader(p)) {
  2443				init_task_pid(p, PIDTYPE_TGID, pid);
  2444				init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
  2445				init_task_pid(p, PIDTYPE_SID, task_session(current));
  2446	
  2447				if (is_child_reaper(pid)) {
  2448					ns_of_pid(pid)->child_reaper = p;
  2449					p->signal->flags |= SIGNAL_UNKILLABLE;
  2450				}
  2451				p->signal->shared_pending.signal = delayed.signal;
  2452				p->signal->tty = tty_kref_get(current->signal->tty);
  2453				/*
  2454				 * Inherit has_child_subreaper flag under the same
  2455				 * tasklist_lock with adding child to the process tree
  2456				 * for propagate_has_child_subreaper optimization.
  2457				 */
  2458				p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
  2459								 p->real_parent->signal->is_child_subreaper;
  2460				list_add_tail(&p->sibling, &p->real_parent->children);
  2461				list_add_tail(&p->cabd, &p->caba->cabds);
  2462				list_add_tail_rcu(&p->tasks, &init_task.tasks);
  2463				attach_pid(p, PIDTYPE_TGID);
  2464				attach_pid(p, PIDTYPE_PGID);
  2465				attach_pid(p, PIDTYPE_SID);
  2466				__this_cpu_inc(process_counts);
  2467			} else {
  2468				current->signal->nr_threads++;
  2469				atomic_inc(&current->signal->live);
  2470				refcount_inc(&current->signal->sigcnt);
  2471				task_join_group_stop(p);
  2472				list_add_tail_rcu(&p->thread_group,
  2473						  &p->group_leader->thread_group);
  2474				list_add_tail_rcu(&p->thread_node,
  2475						  &p->signal->thread_head);
  2476			}
  2477			attach_pid(p, PIDTYPE_PID);
  2478			nr_threads++;
  2479		}
  2480		total_forks++;
  2481		hlist_del_init(&delayed.node);
  2482		spin_unlock(&current->sighand->siglock);
  2483		syscall_tracepoint_update(p);
  2484		write_unlock_irq(&tasklist_lock);
  2485	
  2486		if (pidfile)
  2487			fd_install(pidfd, pidfile);
  2488	
  2489		proc_fork_connector(p);
  2490		sched_post_fork(p);
  2491		cgroup_post_fork(p, args);
  2492		perf_event_fork(p);
  2493	
  2494		trace_task_newtask(p, clone_flags);
  2495		uprobe_copy_process(p, clone_flags);
  2496	
  2497		copy_oom_score_adj(clone_flags, p);
  2498	
  2499		return p;
  2500	
  2501	bad_fork_cancel_cgroup:
  2502		sched_core_free(p);
  2503		spin_unlock(&current->sighand->siglock);
  2504		write_unlock_irq(&tasklist_lock);
  2505		cgroup_cancel_fork(p, args);
  2506	bad_fork_put_pidfd:
  2507		if (clone_flags & CLONE_PIDFD) {
  2508			fput(pidfile);
  2509			put_unused_fd(pidfd);
  2510		}
  2511	bad_fork_free_pid:
  2512		if (pid != &init_struct_pid)
  2513			free_pid(pid);
  2514	bad_fork_cleanup_thread:
  2515		exit_thread(p);
  2516	bad_fork_cleanup_io:
  2517		if (p->io_context)
  2518			exit_io_context(p);
  2519	bad_fork_cleanup_namespaces:
  2520		exit_task_namespaces(p);
  2521	bad_fork_cleanup_mm:
  2522		if (p->mm) {
  2523			mm_clear_owner(p->mm, p);
  2524			mmput(p->mm);
  2525		}
  2526	bad_fork_cleanup_signal:
  2527		if (!(clone_flags & CLONE_THREAD))
  2528			free_signal_struct(p->signal);
  2529	bad_fork_cleanup_sighand:
  2530		__cleanup_sighand(p->sighand);
  2531	bad_fork_cleanup_fs:
  2532		exit_fs(p); /* blocking */
  2533	bad_fork_cleanup_files:
  2534		exit_files(p); /* blocking */
  2535	bad_fork_cleanup_semundo:
  2536		exit_sem(p);
  2537	bad_fork_cleanup_security:
  2538		security_task_free(p);
  2539	bad_fork_cleanup_audit:
  2540		audit_free(p);
  2541	bad_fork_cleanup_perf:
  2542		perf_event_free_task(p);
  2543	bad_fork_cleanup_policy:
  2544		lockdep_free_task(p);
  2545	#ifdef CONFIG_NUMA
  2546		mpol_put(p->mempolicy);
  2547	#endif
  2548	bad_fork_cleanup_delayacct:
  2549		delayacct_tsk_free(p);
  2550	bad_fork_cleanup_count:
  2551		dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
  2552		exit_creds(p);
  2553	bad_fork_free:
  2554		WRITE_ONCE(p->__state, TASK_DEAD);
  2555		exit_task_stack_account(p);
  2556		put_task_stack(p);
  2557		delayed_free_task(p);
  2558	fork_out:
  2559		spin_lock_irq(&current->sighand->siglock);
  2560		hlist_del_init(&delayed.node);
  2561		spin_unlock_irq(&current->sighand->siglock);
  2562		return ERR_PTR(retval);
  2563	}
  2564	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] Add CABA tree to task_struct
  2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
                     ` (3 preceding siblings ...)
  2022-09-09  1:02   ` kernel test robot
@ 2022-09-11 19:27   ` kernel test robot
  4 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-09-11 19:27 UTC (permalink / raw)
  To: Pavel Tikhomirov, Eric Biederman, Alexander Viro,
	Christian Brauner, Andrei Vagin, linux-kernel
  Cc: kbuild-all, Pavel Tikhomirov, Kees Cook, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman,
	Daniel Bristot de Oliveira, Valentin Schneider, Andrew Morton,
	Linux Memory Management List, linux-ia64, linux-fsdevel, kernel

Hi Pavel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on kees/for-next/execve tip/sched/core linus/master v6.0-rc4 next-20220909]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
config: ia64-randconfig-s041-20220911 (https://download.01.org/0day-ci/archive/20220912/202209120356.YizhqUik-lkp@intel.com/config)
compiler: ia64-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/17a897a33137d4f49f99c8be8d619f6f711fccdb
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Pavel-Tikhomirov/Introduce-CABA-helper-process-tree/20220908-220639
        git checkout 17a897a33137d4f49f99c8be8d619f6f711fccdb
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=ia64 SHELL=/bin/bash arch/ia64/kernel/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

sparse warnings: (new ones prefixed by >>)
   arch/ia64/kernel/mca.c:504:1: sparse: sparse: symbol 'search_mca_table' was not declared. Should it be static?
   arch/ia64/kernel/mca.c:607:1: sparse: sparse: symbol 'ia64_mca_register_cpev' was not declared. Should it be static?
   arch/ia64/kernel/mca.c:831:5: sparse: sparse: symbol 'ia64_mca_ucmc_extension' was not declared. Should it be static?
   arch/ia64/kernel/mca.c:1793:36: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct *group_leader @@
   arch/ia64/kernel/mca.c:1793:36: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   arch/ia64/kernel/mca.c:1793:36: sparse:     got struct task_struct *group_leader
>> arch/ia64/kernel/mca.c:1796:17: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *caba @@     got struct task_struct *p @@
   arch/ia64/kernel/mca.c:1796:17: sparse:     expected struct task_struct [noderef] __rcu *caba
   arch/ia64/kernel/mca.c:1796:17: sparse:     got struct task_struct *p
   arch/ia64/kernel/mca.c:2106:43: sparse: sparse: Using plain integer as NULL pointer

vim +1796 arch/ia64/kernel/mca.c

  1770	
  1771	/* Minimal format of the MCA/INIT stacks.  The pseudo processes that run on
  1772	 * these stacks can never sleep, they cannot return from the kernel to user
  1773	 * space, they do not appear in a normal ps listing.  So there is no need to
  1774	 * format most of the fields.
  1775	 */
  1776	
  1777	static void
  1778	format_mca_init_stack(void *mca_data, unsigned long offset,
  1779			const char *type, int cpu)
  1780	{
  1781		struct task_struct *p = (struct task_struct *)((char *)mca_data + offset);
  1782		struct thread_info *ti;
  1783		memset(p, 0, KERNEL_STACK_SIZE);
  1784		ti = task_thread_info(p);
  1785		ti->flags = _TIF_MCA_INIT;
  1786		ti->preempt_count = 1;
  1787		ti->task = p;
  1788		ti->cpu = cpu;
  1789		p->stack = ti;
  1790		p->__state = TASK_UNINTERRUPTIBLE;
  1791		cpumask_set_cpu(cpu, &p->cpus_mask);
  1792		INIT_LIST_HEAD(&p->tasks);
  1793		p->parent = p->real_parent = p->group_leader = p;
  1794		INIT_LIST_HEAD(&p->children);
  1795		INIT_LIST_HEAD(&p->sibling);
> 1796		p->caba = p;
  1797		INIT_LIST_HEAD(&p->cabds);
  1798		INIT_LIST_HEAD(&p->cabd);
  1799		strncpy(p->comm, type, sizeof(p->comm)-1);
  1800	}
  1801	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-09-11 19:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-08 14:03 [PATCH v3 0/2] Introduce CABA helper process tree Pavel Tikhomirov
2022-09-08 14:03 ` [PATCH v3 1/2] Add CABA tree to task_struct Pavel Tikhomirov
2022-09-08 21:29   ` kernel test robot
2022-09-08 22:15     ` Pavel Tikhomirov
2022-09-08 22:09   ` [PATCH v4 " Pavel Tikhomirov
2022-09-08 23:51   ` [PATCH v3 " kernel test robot
2022-09-09  1:02   ` kernel test robot
2022-09-11 19:27   ` kernel test robot
2022-09-08 14:03 ` [PATCH v3 2/2] tests: Add CABA selftest Pavel Tikhomirov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).