mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Peter Zijlstra <peterz@infradead.org>, Ingo Molnar <mingo@redhat.com>
Cc: linux-kernel@vger.kernel.org,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
	Valentin Schneider <vschneid@redhat.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Michal Clapinski <mclapinski@google.com>,
	Andrei Vagin <avagin@gmail.com>, Shuah Khan <shuah@kernel.org>,
	Aniket Gattani <aniketgattani@google.com>,
	linux-kselftest@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Chris Gellermann <christian.gellermann@codasip.com>,
	Bala-Vignesh-Reddy <reddybalavignesh9979@gmail.com>,
	Wei Yang <richard.weiyang@gmail.com>,
	Thomas Gleixner <tglx@kernel.org>,
	Huacai Chen <chenhuacai@kernel.org>,
	WANG Xuerui <kernel@xen0n.name>,
	loongarch@lists.linux.dev,
	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	Helge Deller <deller@gmx.de>,
	John David Anglin <dave.anglin@bell.net>,
	linux-parisc@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>, Guo Ren <guoren@kernel.org>,
	linux-doc@vger.kernel.org, linux-riscv@lists.infradead.org,
	linux-csky@vger.kernel.org, Jonas Bonn <jonas@southpole.se>,
	Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>,
	Stafford Horne <shorne@gmail.com>,
	linux-openrisc@vger.kernel.org,
	Yoshinori Sato <ysato@users.sourceforge.jp>,
	Rich Felker <dalias@libc.org>,
	John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>,
	linux-sh@vger.kernel.org, Chris Zankel <chris@zankel.net>,
	Max Filippov <jcmvbkbc@gmail.com>,
	linux-arch@vger.kernel.org, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	linux-arm-kernel@lists.infradead.org,
	Andy Lutomirski <luto@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Andrea Parri <parri.andrea@gmail.com>,
	Boqun Feng <boqun@kernel.org>,
	Nicholas Piggin <npiggin@gmail.com>,
	David Howells <dhowells@redhat.com>,
	Jade Alglave <j.alglave@ucl.ac.uk>,
	Luc Maranget <luc.maranget@inria.fr>,
	Akira Yokosawa <akiyks@gmail.com>,
	Daniel Lustig <dlustig@nvidia.com>,
	Joel Fernandes <joelagnelf@nvidia.com>,
	lkmm@lists.linux.dev, bpf@vger.kernel.org,
	Naveen N Rao <naveen@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	linux-trace-kernel@vger.kernel.org
Subject: [RFC PATCH 07/16] selftests/membarrier: Test command arguments and registration lifetime
Date: Fri, 13 Nov 2026 08:18:54 -0500	[thread overview]
Message-ID: <20261113131903.157186-8-mathieu.desnoyers@efficios.com> (raw)
In-Reply-To: <20261113131903.157186-1-mathieu.desnoyers@efficios.com>

The existing tests issue each command once with valid arguments, in
one fixed order of registrations. They miss the following:

 - the query mask is not compared with the commands which the kernel
   accepts. Commit 809232619f5b ("sched/membarrier: Fix
   membarrier-rseq fence command missing from query bitmask") fixed
   such a mismatch,
 - only MEMBARRIER_CMD_QUERY is tested with an invalid flag,
 - only the stress test issues the rseq command. Its registration,
   its -EPERM result and its CPU argument are not checked,
 - each registration is not tested alone. Commit fc0d77387cb5
   ("sched/membarrier: Fix private expedited registration check")
   fixed an interaction between two registrations,
 - the registrations are not tested across fork, exec and CLONE_VM.

Add membarrier_test_cmd for those. It uses the kselftest harness,
which runs each test in its own process. A registration cannot be
undone, so each test needs a new process.

The sync core and rseq registration tests fail without commit
"sched/membarrier: Report only completed registrations".

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
 tools/testing/selftests/membarrier/.gitignore |   1 +
 tools/testing/selftests/membarrier/Makefile   |   1 +
 .../membarrier/membarrier_test_cmd.c          | 352 ++++++++++++++++++
 3 files changed, 354 insertions(+)
 create mode 100644 tools/testing/selftests/membarrier/membarrier_test_cmd.c

diff --git a/tools/testing/selftests/membarrier/.gitignore b/tools/testing/selftests/membarrier/.gitignore
index 58969a5e4613..45b995b884a6 100644
--- a/tools/testing/selftests/membarrier/.gitignore
+++ b/tools/testing/selftests/membarrier/.gitignore
@@ -3,3 +3,4 @@ membarrier_test_multi_thread
 membarrier_test_single_thread
 membarrier_rseq_stress
 membarrier_test_ipi
+membarrier_test_cmd
diff --git a/tools/testing/selftests/membarrier/Makefile b/tools/testing/selftests/membarrier/Makefile
index ee5b9deb808b..c7fa0573e978 100644
--- a/tools/testing/selftests/membarrier/Makefile
+++ b/tools/testing/selftests/membarrier/Makefile
@@ -5,6 +5,7 @@ LDLIBS += -lpthread
 TEST_GEN_PROGS := membarrier_test_single_thread \
 		membarrier_test_multi_thread \
 		membarrier_test_ipi \
+		membarrier_test_cmd \
 		membarrier_rseq_stress
 
 LOCAL_HDRS += membarrier_test_impl.h
diff --git a/tools/testing/selftests/membarrier/membarrier_test_cmd.c b/tools/testing/selftests/membarrier/membarrier_test_cmd.c
new file mode 100644
index 000000000000..5982861f77b6
--- /dev/null
+++ b/tools/testing/selftests/membarrier/membarrier_test_cmd.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Check the membarrier command arguments and the lifetime of the
+ * registrations.
+ *
+ * The test harness runs each test in its own process. This matters
+ * because a membarrier registration cannot be undone.
+ */
+#define _GNU_SOURCE
+#include <linux/membarrier.h>
+#include <sys/wait.h>
+#include <syscall.h>
+#include <limits.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+
+#include "kselftest_harness.h"
+
+#define STACK_SIZE	(64 * 1024)
+
+#define REGISTER_CMDS						\
+	(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED |		\
+	 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED |		\
+	 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE |	\
+	 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ)
+
+/* Pairs of registration command and command which needs it. */
+static const struct {
+	int register_cmd;
+	int cmd;
+} private_cmds[] = {
+	{ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
+	  MEMBARRIER_CMD_PRIVATE_EXPEDITED },
+	{ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
+	  MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE },
+	{ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ,
+	  MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ },
+};
+
+static int sys_membarrier(int cmd, unsigned int flags, int cpu_id)
+{
+	return syscall(__NR_membarrier, cmd, flags, cpu_id);
+}
+
+static int query(void)
+{
+	return sys_membarrier(MEMBARRIER_CMD_QUERY, 0, 0);
+}
+
+static int get_registrations(void)
+{
+	return sys_membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0, 0);
+}
+
+/* Each command is either in the query mask or returns -EINVAL. */
+TEST(query_matches_commands)
+{
+	int mask = query(), bit, ret;
+
+	ASSERT_GE(mask, 0);
+	for (bit = 0; bit < 32; bit++) {
+		int cmd = (int)(1U << bit);
+
+		errno = 0;
+		ret = sys_membarrier(cmd, 0, 0);
+		if (mask & cmd) {
+			EXPECT_NE(errno, EINVAL) {
+				TH_LOG("command 0x%x is in the query mask", cmd);
+			}
+		} else {
+			EXPECT_EQ(ret, -1);
+			EXPECT_EQ(errno, EINVAL) {
+				TH_LOG("command 0x%x is not in the query mask", cmd);
+			}
+		}
+	}
+}
+
+/* A command is a single bit. */
+TEST(invalid_commands)
+{
+	static const int cmds[] = {
+		-1, INT_MAX,
+		MEMBARRIER_CMD_GLOBAL | MEMBARRIER_CMD_GLOBAL_EXPEDITED,
+		MEMBARRIER_CMD_PRIVATE_EXPEDITED |
+			MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+		EXPECT_EQ(sys_membarrier(cmds[i], 0, 0), -1);
+		EXPECT_EQ(errno, EINVAL);
+	}
+}
+
+/* Only the rseq command accepts a flag: MEMBARRIER_CMD_FLAG_CPU. */
+TEST(invalid_flags)
+{
+	static const unsigned int flags[] = {
+		MEMBARRIER_CMD_FLAG_CPU, 1U << 1, 1U << 31, ~0U,
+		MEMBARRIER_CMD_FLAG_CPU | (1U << 1),
+	};
+	int mask = query(), bit, i;
+
+	ASSERT_GE(mask, 0);
+	/* Bit -1 stands for MEMBARRIER_CMD_QUERY, which is 0. */
+	for (bit = -1; bit < 32; bit++) {
+		int cmd = bit < 0 ? MEMBARRIER_CMD_QUERY : (int)(1U << bit);
+
+		if (cmd && !(mask & cmd))
+			continue;
+		for (i = 0; i < ARRAY_SIZE(flags); i++) {
+			if (cmd == MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ &&
+			    flags[i] == MEMBARRIER_CMD_FLAG_CPU)
+				continue;
+			EXPECT_EQ(sys_membarrier(cmd, flags[i], 0), -1);
+			EXPECT_EQ(errno, EINVAL) {
+				TH_LOG("command 0x%x flags 0x%x", cmd, flags[i]);
+			}
+		}
+	}
+}
+
+/* A private command needs its own registration. */
+TEST(private_needs_registration)
+{
+	int mask = query(), registered = get_registrations(), i;
+
+	ASSERT_GE(mask, 0);
+	ASSERT_GE(registered, 0);
+	for (i = 0; i < ARRAY_SIZE(private_cmds); i++) {
+		if (!(mask & private_cmds[i].cmd))
+			continue;
+		/* The C library may have registered already. */
+		if (registered & private_cmds[i].register_cmd)
+			continue;
+		EXPECT_EQ(sys_membarrier(private_cmds[i].cmd, 0, 0), -1);
+		EXPECT_EQ(errno, EPERM);
+	}
+	if ((mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ) &&
+	    !(registered & MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ)) {
+		EXPECT_EQ(sys_membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
+					 MEMBARRIER_CMD_FLAG_CPU, 0), -1);
+		EXPECT_EQ(errno, EPERM);
+	}
+}
+
+/*
+ * Issue one registration command. It must add its own bit to the
+ * registrations, and no other bit. It must allow its own command, and
+ * no other command.
+ */
+static void register_one(struct __test_metadata *_metadata, int register_cmd)
+{
+	int mask = query(), before = get_registrations(), i;
+
+	ASSERT_GE(mask, 0);
+	ASSERT_GE(before, 0);
+	if (!(mask & register_cmd))
+		SKIP(return, "command 0x%x is not available", register_cmd);
+	ASSERT_EQ(sys_membarrier(register_cmd, 0, 0), 0);
+	EXPECT_EQ(get_registrations(), before | register_cmd);
+	/* A second registration succeeds and changes nothing. */
+	ASSERT_EQ(sys_membarrier(register_cmd, 0, 0), 0);
+	EXPECT_EQ(get_registrations(), before | register_cmd);
+
+	for (i = 0; i < ARRAY_SIZE(private_cmds); i++) {
+		if (!(mask & private_cmds[i].cmd))
+			continue;
+		if ((before | register_cmd) & private_cmds[i].register_cmd) {
+			EXPECT_EQ(sys_membarrier(private_cmds[i].cmd, 0, 0), 0);
+		} else {
+			EXPECT_EQ(sys_membarrier(private_cmds[i].cmd, 0, 0), -1);
+			EXPECT_EQ(errno, EPERM);
+		}
+	}
+}
+
+TEST(register_global_expedited)
+{
+	register_one(_metadata, MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED);
+}
+
+TEST(register_private_expedited)
+{
+	register_one(_metadata, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED);
+}
+
+TEST(register_private_expedited_sync_core)
+{
+	register_one(_metadata,
+		     MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE);
+}
+
+TEST(register_private_expedited_rseq)
+{
+	register_one(_metadata, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ);
+}
+
+/* Register every command, one at a time. Return the registrations. */
+static int register_all(struct __test_metadata *_metadata)
+{
+	int mask = query(), expected = get_registrations(), bit;
+
+	for (bit = 0; bit < 31; bit++) {
+		int cmd = 1 << bit;
+
+		if (!(cmd & REGISTER_CMDS & mask))
+			continue;
+		ASSERT_EQ(sys_membarrier(cmd, 0, 0), 0);
+		expected |= cmd;
+		EXPECT_EQ(get_registrations(), expected);
+	}
+	return expected;
+}
+
+TEST(register_all_commands)
+{
+	register_all(_metadata);
+}
+
+static void *thread_pause(void *arg)
+{
+	for (;;)
+		pause();
+	return NULL;
+}
+
+/*
+ * The rseq command accepts any CPU number. It ignores a CPU which does
+ * not exist. A negative CPU number selects all CPUs.
+ *
+ * The kernel only looks at the CPU number of a multi-threaded process,
+ * so keep a second thread alive.
+ */
+TEST(rseq_cpu_argument)
+{
+	static const int cpus[] = { 0, INT_MAX, -1, INT_MIN };
+	pthread_t thread;
+	int i;
+
+	if (!(query() & MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ))
+		SKIP(return, "the rseq command is not available");
+	ASSERT_EQ(pthread_create(&thread, NULL, thread_pause, NULL), 0);
+	ASSERT_EQ(sys_membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ,
+				 0, 0), 0);
+	EXPECT_EQ(sys_membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
+				 MEMBARRIER_CMD_FLAG_CPU, sched_getcpu()), 0);
+	for (i = 0; i < ARRAY_SIZE(cpus); i++) {
+		EXPECT_EQ(sys_membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
+					 MEMBARRIER_CMD_FLAG_CPU, cpus[i]), 0) {
+			TH_LOG("cpu_id %d", cpus[i]);
+		}
+	}
+	/* Without the flag, the CPU argument is ignored. */
+	EXPECT_EQ(sys_membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
+				 0, INT_MAX), 0);
+}
+
+/* A forked child inherits the registrations. */
+TEST(fork_inherits_registrations)
+{
+	int expected = register_all(_metadata), status;
+	pid_t pid;
+
+	pid = fork();
+	ASSERT_GE(pid, 0);
+	if (!pid)
+		_exit(get_registrations() != expected);
+	ASSERT_EQ(waitpid(pid, &status, 0), pid);
+	EXPECT_TRUE(WIFEXITED(status));
+	EXPECT_EQ(WEXITSTATUS(status), 0);
+}
+
+/*
+ * exec() drops the registrations. The new program image starts with
+ * the registrations which this test program had when it started.
+ */
+static int initial_registrations;
+
+TEST(exec_drops_registrations)
+{
+	char expected[16];
+	int status;
+	pid_t pid;
+
+	register_all(_metadata);
+	snprintf(expected, sizeof(expected), "%d", initial_registrations);
+	pid = fork();
+	ASSERT_GE(pid, 0);
+	if (!pid) {
+		execl("/proc/self/exe", "membarrier_test_cmd",
+		      "--expect-registrations", expected, NULL);
+		_exit(2);
+	}
+	ASSERT_EQ(waitpid(pid, &status, 0), pid);
+	EXPECT_TRUE(WIFEXITED(status));
+	if (WEXITSTATUS(status) == 2)
+		SKIP(return, "cannot exec /proc/self/exe");
+	EXPECT_EQ(WEXITSTATUS(status), 0);
+}
+
+static int clone_vm_fn(void *arg)
+{
+	int cmd = *(int *)arg;
+
+	return sys_membarrier(cmd, 0, 0) ? 1 : 0;
+}
+
+/*
+ * The registrations belong to the mm. A task of another thread group
+ * which shares the mm (CLONE_VM without CLONE_THREAD) registers for
+ * both thread groups.
+ */
+TEST(clone_vm_shares_registrations)
+{
+	int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED;
+	int before = get_registrations(), status;
+	char *stack;
+	pid_t pid;
+
+	ASSERT_GE(before, 0);
+	stack = malloc(STACK_SIZE);
+	ASSERT_NE(stack, NULL);
+	pid = clone(clone_vm_fn, stack + STACK_SIZE, CLONE_VM | SIGCHLD, &cmd);
+	ASSERT_GE(pid, 0);
+	ASSERT_EQ(waitpid(pid, &status, 0), pid);
+	EXPECT_TRUE(WIFEXITED(status));
+	EXPECT_EQ(WEXITSTATUS(status), 0);
+	EXPECT_EQ(get_registrations(), before | cmd);
+	EXPECT_EQ(sys_membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0), 0);
+	free(stack);
+}
+
+int main(int argc, char **argv)
+{
+	/* New program image of exec_drops_registrations. */
+	if (argc == 3 && !strcmp(argv[1], "--expect-registrations"))
+		return get_registrations() != atoi(argv[2]);
+
+	if (query() < 0)
+		ksft_exit_skip("sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");
+	initial_registrations = get_registrations();
+	if (initial_registrations < 0)
+		ksft_exit_skip("MEMBARRIER_CMD_GET_REGISTRATIONS is not available.\n");
+	return test_harness_run(argc, argv);
+}
-- 
2.47.3


  parent reply	other threads:[~2026-11-13 13:19 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 13:18 [RFC PATCH 00/16] membarrier: fixes, selftests and documentation Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 01/16] sched/membarrier: Fix stale runqueue state after a lazy mm switch Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 02/16] sched/membarrier: Report only completed registrations Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 03/16] selftests/membarrier: Rebuild the tests when their header changes Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 04/16] selftests/membarrier: Issue the sync core command in its test Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 05/16] selftests/membarrier: Run the tests on nohz_full kernels Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 06/16] selftests/membarrier: Test which CPUs the expedited commands interrupt Mathieu Desnoyers
2026-11-13 13:18 ` Mathieu Desnoyers [this message]
2026-11-13 13:18 ` [RFC PATCH 08/16] LoongArch: membarrier: Add full memory barrier in switch_mm() Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 09/16] parisc: " Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 10/16] Documentation/membarrier: Update the per-architecture barrier list Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 11/16] Documentation/features: Update the membarrier sync core requirements Mathieu Desnoyers
2026-11-13 13:18 ` [RFC PATCH 12/16] x86/entry: Remove stale membarrier sync core comments Mathieu Desnoyers
2026-11-13 13:19 ` [RFC PATCH 13/16] selftests/membarrier: Add litmus tests of the memory ordering Mathieu Desnoyers
2026-11-13 13:19 ` [RFC PATCH 14/16] MAINTAINERS: Add the membarrier selftests to MEMBARRIER SUPPORT Mathieu Desnoyers
2026-11-13 13:19 ` [RFC PATCH 15/16] selftests/membarrier: Check the memory barriers of each thread Mathieu Desnoyers
2026-11-13 13:19 ` [RFC PATCH 16/16] selftests/membarrier: Check the core serialization of the sync core command Mathieu Desnoyers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261113131903.157186-8-mathieu.desnoyers@efficios.com \
    --to=mathieu.desnoyers@efficios.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=akiyks@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex@ghiti.fr \
    --cc=aniketgattani@google.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=avagin@gmail.com \
    --cc=boqun@kernel.org \
    --cc=bp@alien8.de \
    --cc=bpf@vger.kernel.org \
    --cc=bsegall@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=chenhuacai@kernel.org \
    --cc=chris@zankel.net \
    --cc=christian.gellermann@codasip.com \
    --cc=corbet@lwn.net \
    --cc=dalias@libc.org \
    --cc=dave.anglin@bell.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=deller@gmx.de \
    --cc=dhowells@redhat.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=dlustig@nvidia.com \
    --cc=glaubitz@physik.fu-berlin.de \
    --cc=guoren@kernel.org \
    --cc=hpa@zytor.com \
    --cc=j.alglave@ucl.ac.uk \
    --cc=jcmvbkbc@gmail.com \
    --cc=joelagnelf@nvidia.com \
    --cc=jonas@southpole.se \
    --cc=juri.lelli@redhat.com \
    --cc=kernel@xen0n.name \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-csky@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-openrisc@vger.kernel.org \
    --cc=linux-parisc@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-sh@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=lkmm@lists.linux.dev \
    --cc=loongarch@lists.linux.dev \
    --cc=luc.maranget@inria.fr \
    --cc=luto@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mclapinski@google.com \
    --cc=mgorman@suse.de \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=naveen@kernel.org \
    --cc=npiggin@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=parri.andrea@gmail.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pjw@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=reddybalavignesh9979@gmail.com \
    --cc=richard.weiyang@gmail.com \
    --cc=rostedt@goodmis.org \
    --cc=shorne@gmail.com \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=stefan.kristiansson@saunalahti.fi \
    --cc=stern@rowland.harvard.edu \
    --cc=tglx@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    --cc=ysato@users.sourceforge.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®