linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, arnd@arndb.de, keescook@chromium.org,
	linux-mm@kvack.org, linux@roeck-us.net, mcroce@microsoft.com,
	mm-commits@vger.kernel.org, natechancellor@gmail.com,
	pasha.tatashin@soleen.com, pmladek@suse.com, rppt@kernel.org,
	torvalds@linux-foundation.org, tyhicks@linux.microsoft.com
Subject: [patch 84/95] reboot: allow to specify reboot mode via sysfs
Date: Tue, 15 Dec 2020 20:46:57 -0800	[thread overview]
Message-ID: <20201216044657.SBwU69OF0%akpm@linux-foundation.org> (raw)
In-Reply-To: <20201215204156.f05ec694b907845bcfab5c44@linux-foundation.org>

From: Matteo Croce <mcroce@microsoft.com>
Subject: reboot: allow to specify reboot mode via sysfs

The kernel cmdline reboot= option offers some sort of control on how the
reboot is issued.

We don't always know in advance what type of reboot to perform.

Sometimes a warm reboot is preferred to persist certain memory regions
across the reboot.  Others a cold one is needed to apply a future
system update that makes a memory memory model change, like changing
the base page size or resizing a persistent memory region.

Or simply we want to enable reboot_force because we noticed that
something bad happened.

Add handles in sysfs to allow setting these reboot options, so they can
be changed when the system is booted, other than at boot time.

The handlers are under <sysfs>/kernel/reboot, can be read to get the
current configuration and written to alter it.

	# cd /sys/kernel/reboot/

	# grep . *
	cpu:0
	force:0
	mode:cold
	type:acpi

	# echo 2 >cpu
	# echo yes >force
	# echo soft >mode
	# echo bios >type

	# grep . *
	cpu:2
	force:1
	mode:soft
	type:bios

Before setting anything, check for CAP_SYS_BOOT capability, so it's
possible to allow an unpriviledged process to change these settings simply
by relaxing the handles permissions, without opening them to the world.

[natechancellor@gmail.com: fix variable assignments in type_store]
  Link: https://lkml.kernel.org/r/20201112035023.974748-1-natechancellor@gmail.com
  Link: https://github.com/ClangBuiltLinux/linux/issues/1197
Link: https://lkml.kernel.org/r/20201110202746.9690-1-mcroce@linux.microsoft.com
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Tyler Hicks <tyhicks@linux.microsoft.com>
Cc: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 Documentation/ABI/testing/sysfs-kernel-reboot |   32 ++
 kernel/reboot.c                               |  206 ++++++++++++++++
 2 files changed, 238 insertions(+)

--- /dev/null
+++ a/Documentation/ABI/testing/sysfs-kernel-reboot
@@ -0,0 +1,32 @@
+What:		/sys/kernel/reboot
+Date:		November 2020
+KernelVersion:	5.11
+Contact:	Matteo Croce <mcroce@microsoft.com>
+Description:	Interface to set the kernel reboot behavior, similarly to
+		what can be done via the reboot= cmdline option.
+		(see Documentation/admin-guide/kernel-parameters.txt)
+
+What:		/sys/kernel/reboot/mode
+Date:		November 2020
+KernelVersion:	5.11
+Contact:	Matteo Croce <mcroce@microsoft.com>
+Description:	Reboot mode. Valid values are: cold warm hard soft gpio
+
+What:		/sys/kernel/reboot/type
+Date:		November 2020
+KernelVersion:	5.11
+Contact:	Matteo Croce <mcroce@microsoft.com>
+Description:	Reboot type. Valid values are: bios acpi kbd triple efi pci
+
+What:		/sys/kernel/reboot/cpu
+Date:		November 2020
+KernelVersion:	5.11
+Contact:	Matteo Croce <mcroce@microsoft.com>
+Description:	CPU number to use to reboot.
+
+What:		/sys/kernel/reboot/force
+Date:		November 2020
+KernelVersion:	5.11
+Contact:	Matteo Croce <mcroce@microsoft.com>
+Description:	Don't wait for any other CPUs on reboot and
+		avoid anything that could hang.
--- a/kernel/reboot.c~reboot-allow-to-specify-reboot-mode-via-sysfs
+++ a/kernel/reboot.c
@@ -600,3 +600,209 @@ static int __init reboot_setup(char *str
 	return 1;
 }
 __setup("reboot=", reboot_setup);
+
+#ifdef CONFIG_SYSFS
+
+#define REBOOT_COLD_STR		"cold"
+#define REBOOT_WARM_STR		"warm"
+#define REBOOT_HARD_STR		"hard"
+#define REBOOT_SOFT_STR		"soft"
+#define REBOOT_GPIO_STR		"gpio"
+#define REBOOT_UNDEFINED_STR	"undefined"
+
+#define BOOT_TRIPLE_STR		"triple"
+#define BOOT_KBD_STR		"kbd"
+#define BOOT_BIOS_STR		"bios"
+#define BOOT_ACPI_STR		"acpi"
+#define BOOT_EFI_STR		"efi"
+#define BOOT_CF9_FORCE_STR	"cf9_force"
+#define BOOT_CF9_SAFE_STR	"cf9_safe"
+
+static ssize_t mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	const char *val;
+
+	switch (reboot_mode) {
+	case REBOOT_COLD:
+		val = REBOOT_COLD_STR;
+		break;
+	case REBOOT_WARM:
+		val = REBOOT_WARM_STR;
+		break;
+	case REBOOT_HARD:
+		val = REBOOT_HARD_STR;
+		break;
+	case REBOOT_SOFT:
+		val = REBOOT_SOFT_STR;
+		break;
+	case REBOOT_GPIO:
+		val = REBOOT_GPIO_STR;
+		break;
+	default:
+		val = REBOOT_UNDEFINED_STR;
+	}
+
+	return sprintf(buf, "%s\n", val);
+}
+static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr,
+			  const char *buf, size_t count)
+{
+	if (!capable(CAP_SYS_BOOT))
+		return -EPERM;
+
+	if (!strncmp(buf, REBOOT_COLD_STR, strlen(REBOOT_COLD_STR)))
+		reboot_mode = REBOOT_COLD;
+	else if (!strncmp(buf, REBOOT_WARM_STR, strlen(REBOOT_WARM_STR)))
+		reboot_mode = REBOOT_WARM;
+	else if (!strncmp(buf, REBOOT_HARD_STR, strlen(REBOOT_HARD_STR)))
+		reboot_mode = REBOOT_HARD;
+	else if (!strncmp(buf, REBOOT_SOFT_STR, strlen(REBOOT_SOFT_STR)))
+		reboot_mode = REBOOT_SOFT;
+	else if (!strncmp(buf, REBOOT_GPIO_STR, strlen(REBOOT_GPIO_STR)))
+		reboot_mode = REBOOT_GPIO;
+	else
+		return -EINVAL;
+
+	return count;
+}
+static struct kobj_attribute reboot_mode_attr = __ATTR_RW(mode);
+
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	const char *val;
+
+	switch (reboot_type) {
+	case BOOT_TRIPLE:
+		val = BOOT_TRIPLE_STR;
+		break;
+	case BOOT_KBD:
+		val = BOOT_KBD_STR;
+		break;
+	case BOOT_BIOS:
+		val = BOOT_BIOS_STR;
+		break;
+	case BOOT_ACPI:
+		val = BOOT_ACPI_STR;
+		break;
+	case BOOT_EFI:
+		val = BOOT_EFI_STR;
+		break;
+	case BOOT_CF9_FORCE:
+		val = BOOT_CF9_FORCE_STR;
+		break;
+	case BOOT_CF9_SAFE:
+		val = BOOT_CF9_SAFE_STR;
+		break;
+	default:
+		val = REBOOT_UNDEFINED_STR;
+	}
+
+	return sprintf(buf, "%s\n", val);
+}
+static ssize_t type_store(struct kobject *kobj, struct kobj_attribute *attr,
+			  const char *buf, size_t count)
+{
+	if (!capable(CAP_SYS_BOOT))
+		return -EPERM;
+
+	if (!strncmp(buf, BOOT_TRIPLE_STR, strlen(BOOT_TRIPLE_STR)))
+		reboot_type = BOOT_TRIPLE;
+	else if (!strncmp(buf, BOOT_KBD_STR, strlen(BOOT_KBD_STR)))
+		reboot_type = BOOT_KBD;
+	else if (!strncmp(buf, BOOT_BIOS_STR, strlen(BOOT_BIOS_STR)))
+		reboot_type = BOOT_BIOS;
+	else if (!strncmp(buf, BOOT_ACPI_STR, strlen(BOOT_ACPI_STR)))
+		reboot_type = BOOT_ACPI;
+	else if (!strncmp(buf, BOOT_EFI_STR, strlen(BOOT_EFI_STR)))
+		reboot_type = BOOT_EFI;
+	else if (!strncmp(buf, BOOT_CF9_FORCE_STR, strlen(BOOT_CF9_FORCE_STR)))
+		reboot_type = BOOT_CF9_FORCE;
+	else if (!strncmp(buf, BOOT_CF9_SAFE_STR, strlen(BOOT_CF9_SAFE_STR)))
+		reboot_type = BOOT_CF9_SAFE;
+	else
+		return -EINVAL;
+
+	return count;
+}
+static struct kobj_attribute reboot_type_attr = __ATTR_RW(type);
+
+static ssize_t cpu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", reboot_cpu);
+}
+static ssize_t cpu_store(struct kobject *kobj, struct kobj_attribute *attr,
+			  const char *buf, size_t count)
+{
+	unsigned int cpunum;
+	int rc;
+
+	if (!capable(CAP_SYS_BOOT))
+		return -EPERM;
+
+	rc = kstrtouint(buf, 0, &cpunum);
+
+	if (rc)
+		return rc;
+
+	if (cpunum >= num_possible_cpus())
+		return -ERANGE;
+
+	reboot_cpu = cpunum;
+
+	return count;
+}
+static struct kobj_attribute reboot_cpu_attr = __ATTR_RW(cpu);
+
+static ssize_t force_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", reboot_force);
+}
+static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr,
+			  const char *buf, size_t count)
+{
+	bool res;
+
+	if (!capable(CAP_SYS_BOOT))
+		return -EPERM;
+
+	if (kstrtobool(buf, &res))
+		return -EINVAL;
+
+	reboot_force = res;
+
+	return count;
+}
+static struct kobj_attribute reboot_force_attr = __ATTR_RW(force);
+
+static struct attribute *reboot_attrs[] = {
+	&reboot_mode_attr.attr,
+	&reboot_type_attr.attr,
+	&reboot_cpu_attr.attr,
+	&reboot_force_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group reboot_attr_group = {
+	.attrs = reboot_attrs,
+};
+
+static int __init reboot_ksysfs_init(void)
+{
+	struct kobject *reboot_kobj;
+	int ret;
+
+	reboot_kobj = kobject_create_and_add("reboot", kernel_kobj);
+	if (!reboot_kobj)
+		return -ENOMEM;
+
+	ret = sysfs_create_group(reboot_kobj, &reboot_attr_group);
+	if (ret) {
+		kobject_put(reboot_kobj);
+		return ret;
+	}
+
+	return 0;
+}
+late_initcall(reboot_ksysfs_init);
+
+#endif
_


  parent reply	other threads:[~2020-12-16  4:47 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-16  4:41 incoming Andrew Morton
2020-12-16  4:42 ` [patch 01/95] mm: fix a race on nr_swap_pages Andrew Morton
2020-12-16  4:42 ` [patch 02/95] mm/memory_hotplug: quieting offline operation Andrew Morton
2020-12-16  4:42 ` [patch 03/95] alpha: replace bogus in_interrupt() Andrew Morton
2020-12-16  4:42 ` [patch 04/95] procfs: delete duplicated words + other fixes Andrew Morton
2020-12-16  4:42 ` [patch 05/95] proc: provide details on indirect branch speculation Andrew Morton
2020-12-16  4:42 ` [patch 06/95] proc: fix lookup in /proc/net subdirectories after setns(2) Andrew Morton
2020-12-16  4:42 ` [patch 07/95] fs/proc: make pde_get() return nothing Andrew Morton
2020-12-16  4:42 ` [patch 08/95] asm-generic: force inlining of get_order() to work around gcc10 poor decision Andrew Morton
2020-12-16  4:42 ` [patch 09/95] kernel.h: split out mathematical helpers Andrew Morton
2020-12-16  4:42 ` [patch 10/95] kernel/acct.c: use #elif instead of #end and #elif Andrew Morton
2020-12-16  4:42 ` [patch 11/95] include/linux/bitmap.h: convert bitmap_empty() / bitmap_full() to return boolean Andrew Morton
2020-12-16  4:42 ` [patch 12/95] bitmap: remove unused function declaration Andrew Morton
2020-12-16  4:43 ` [patch 13/95] lib/test_free_pages.c: add basic progress indicators Andrew Morton
2020-12-16  4:43 ` [patch 14/95] lib/stackdepot.c: replace one-element array with flexible-array member Andrew Morton
2020-12-16  4:43 ` [patch 15/95] lib/stackdepot.c: use flex_array_size() helper in memcpy() Andrew Morton
2020-12-16  4:43 ` [patch 16/95] lib/stackdepot.c: use array_size() helper in jhash2() Andrew Morton
2020-12-16  4:43 ` [patch 17/95] lib/test_lockup.c: minimum fix to get it compiled on PREEMPT_RT Andrew Morton
2020-12-16  4:43 ` [patch 18/95] lib/list_kunit: follow new file name convention for KUnit tests Andrew Morton
2020-12-16  6:02   ` Linus Torvalds
2020-12-16  6:53     ` David Gow
2020-12-16  7:01       ` Linus Torvalds
2020-12-16 10:41       ` Andy Shevchenko
2020-12-17  9:21         ` David Gow
2020-12-17 12:02           ` Andy Shevchenko
2020-12-16  4:43 ` [patch 19/95] lib/linear_ranges_kunit: " Andrew Morton
2020-12-16  4:43 ` [patch 20/95] lib/bits_kunit: " Andrew Morton
2020-12-16  4:43 ` [patch 21/95] lib/cmdline: fix get_option() for strings starting with hyphen Andrew Morton
2020-12-16  4:43 ` [patch 22/95] lib/cmdline: allow NULL to be an output for get_option() Andrew Morton
2020-12-16  4:43 ` [patch 23/95] lib/cmdline_kunit: add a new test suite for cmdline API Andrew Morton
2020-12-16  4:43 ` [patch 24/95] ilog2: improve ilog2 for constant arguments Andrew Morton
2020-12-16  4:43 ` [patch 25/95] lib/string: remove unnecessary #undefs Andrew Morton
2020-12-16  4:43 ` [patch 26/95] lib: string.h: detect intra-object overflow in fortified string functions Andrew Morton
2020-12-16  4:43 ` [patch 27/95] lkdtm: tests for FORTIFY_SOURCE Andrew Morton
2020-12-16  4:43 ` [patch 28/95] string.h: add FORTIFY coverage for strscpy() Andrew Morton
2020-12-16  7:26   ` Linus Torvalds
2020-12-16  4:43 ` [patch 29/95] drivers/misc/lkdtm: add new file in LKDTM to test fortified strscpy Andrew Morton
2020-12-16  4:43 ` [patch 30/95] drivers/misc/lkdtm/lkdtm.h: correct wrong filenames in comment Andrew Morton
2020-12-16  4:44 ` [patch 31/95] lib: cleanup kstrto*() usage Andrew Morton
2020-12-16  4:44 ` [patch 32/95] lib/lz4: explicitly support in-place decompression Andrew Morton
2020-12-16  4:44 ` [patch 33/95] bitops: introduce the for_each_set_clump macro Andrew Morton
2020-12-16  6:14   ` Linus Torvalds
2020-12-16  4:44 ` [patch 34/95] lib/test_bitmap.c: add for_each_set_clump test cases Andrew Morton
2020-12-16  4:44 ` [patch 35/95] gpio: thunderx: utilize for_each_set_clump macro Andrew Morton
2020-12-16  4:44 ` [patch 36/95] gpio: xilinx: utilize generic bitmap_get_value and _set_value Andrew Morton
2020-12-16  4:44 ` [patch 37/95] checkpatch: add new exception to repeated word check Andrew Morton
2020-12-16  4:44 ` [patch 38/95] checkpatch: fix false positives in REPEATED_WORD warning Andrew Morton
2020-12-16  4:44 ` [patch 39/95] checkpatch: ignore generated CamelCase defines and enum values Andrew Morton
2020-12-16  4:44 ` [patch 40/95] checkpatch: prefer static const declarations Andrew Morton
2020-12-16  4:44 ` [patch 41/95] checkpatch: allow --fix removal of unnecessary break statements Andrew Morton
2020-12-16  4:44 ` [patch 42/95] checkpatch: extend attributes check to handle more patterns Andrew Morton
2020-12-16  4:44 ` [patch 43/95] checkpatch: add a fixer for missing newline at eof Andrew Morton
2020-12-16  4:44 ` [patch 44/95] checkpatch: update __attribute__((section("name"))) quote removal Andrew Morton
2020-12-16  4:44 ` [patch 45/95] checkpatch: add fix option for GERRIT_CHANGE_ID Andrew Morton
2020-12-16  4:44 ` [patch 46/95] checkpatch: add __alias and __weak to suggested __attribute__ conversions Andrew Morton
2020-12-16  4:44 ` [patch 47/95] checkpatch: improve email parsing Andrew Morton
2020-12-16  4:44 ` [patch 48/95] checkpatch: fix spelling errors and remove repeated word Andrew Morton
2020-12-16  4:44 ` [patch 49/95] checkpatch: avoid COMMIT_LOG_LONG_LINE warning for signature tags Andrew Morton
2020-12-16  4:45 ` [patch 50/95] checkpatch: fix unescaped left brace Andrew Morton
2020-12-16  4:45 ` [patch 51/95] checkpatch: add fix option for ASSIGNMENT_CONTINUATIONS Andrew Morton
2020-12-16  4:45 ` [patch 52/95] checkpatch: add fix option for LOGICAL_CONTINUATIONS Andrew Morton
2020-12-16  4:45 ` [patch 53/95] checkpatch: add fix and improve warning msg for non-standard signature Andrew Morton
2020-12-16  4:45 ` [patch 54/95] checkpatch: add warning for unnecessary use of %h[xudi] and %hh[xudi] Andrew Morton
2020-12-16  4:45 ` [patch 55/95] checkpatch: add warning for lines starting with a '#' in commit log Andrew Morton
2020-12-16  4:45 ` [patch 56/95] checkpatch: fix TYPO_SPELLING check for words with apostrophe Andrew Morton
2020-12-16  4:45 ` [patch 57/95] checkpatch: add printk_once and printk_ratelimit to prefer pr_<level> warning Andrew Morton
2020-12-16  4:45 ` [patch 58/95] fs/nilfs2: remove some unused macros to tame gcc Andrew Morton
2020-12-16  4:45 ` [patch 59/95] kdump: append uts_namespace.name offset to VMCOREINFO Andrew Morton
2020-12-16  4:45 ` [patch 60/95] rapidio: remove unused rio_get_asm() and rio_get_device() Andrew Morton
2020-12-16  4:45 ` [patch 61/95] gcov: remove support for GCC < 4.9 Andrew Morton
2020-12-16  4:45 ` [patch 62/95] gcov: fix kernel-doc markup issue Andrew Morton
2020-12-16  4:45 ` [patch 63/95] bfs: don't use WARNING: string when it's just info Andrew Morton
2020-12-16  4:45 ` [patch 64/95] relay: remove unused buf_mapped and buf_unmapped callbacks Andrew Morton
2020-12-16  4:45 ` [patch 65/95] relay: require non-NULL callbacks in relay_open() Andrew Morton
2020-12-16  4:45 ` [patch 66/95] relay: make create_buf_file and remove_buf_file callbacks mandatory Andrew Morton
2020-12-16  4:45 ` [patch 67/95] relay: allow the use of const callback structs Andrew Morton
2020-12-16  4:46 ` [patch 68/95] drm/i915: make relay callbacks const Andrew Morton
2020-12-16  4:46 ` [patch 69/95] ath10k: " Andrew Morton
2020-12-16  4:46 ` [patch 70/95] ath11k: " Andrew Morton
2020-12-16  4:46 ` [patch 71/95] ath9k: " Andrew Morton
2020-12-16  4:46 ` [patch 72/95] blktrace: " Andrew Morton
2020-12-16  4:46 ` [patch 73/95] kernel/resource.c: fix kernel-doc markups Andrew Morton
2020-12-16  4:46 ` [patch 74/95] ubsan: remove redundant -Wno-maybe-uninitialized Andrew Morton
2020-12-16  4:46 ` [patch 75/95] ubsan: move cc-option tests into Kconfig Andrew Morton
2020-12-16  4:46 ` [patch 76/95] ubsan: disable object-size sanitizer under GCC Andrew Morton
2020-12-16  4:46 ` [patch 77/95] ubsan: disable UBSAN_TRAP for all*config Andrew Morton
2020-12-16  4:46 ` [patch 78/95] ubsan: enable for all*config builds Andrew Morton
2020-12-16  4:46 ` [patch 79/95] ubsan: remove UBSAN_MISC in favor of individual options Andrew Morton
2020-12-16  4:46 ` [patch 80/95] ubsan: expand tests and reporting Andrew Morton
2020-12-16  4:46 ` [patch 81/95] kcov: don't instrument with UBSAN Andrew Morton
2020-12-16  4:46 ` [patch 82/95] lib/ubsan.c: mark type_check_kinds with static keyword Andrew Morton
2020-12-16  4:46 ` [patch 83/95] reboot: refactor and comment the cpu selection code Andrew Morton
2020-12-16  4:46 ` Andrew Morton [this message]
2020-12-16  4:47 ` [patch 85/95] reboot: remove cf9_safe from allowed types and rename cf9_force Andrew Morton
2020-12-16  4:47 ` [patch 86/95] reboot: allow to override reboot type if quirks are found Andrew Morton
2020-12-16  4:47 ` [patch 87/95] reboot: hide from sysfs not applicable settings Andrew Morton
2020-12-16  4:47 ` [patch 88/95] fault-injection: handle EI_ETYPE_TRUE Andrew Morton
2020-12-16  4:47 ` [patch 89/95] lib/lzo/lzo1x_compress.c: make lzogeneric1x_1_compress() static Andrew Morton
2020-12-16  4:47 ` [patch 90/95] apparmor: remove duplicate macro list_entry_is_head() Andrew Morton
2020-12-16  4:47 ` [patch 91/95] mm: unexport follow_pte_pmd Andrew Morton
2020-12-16  4:47 ` [patch 92/95] mm: simplify follow_pte{,pmd} Andrew Morton
2020-12-16  4:47 ` [patch 93/95] mm: fix some spelling mistakes in comments Andrew Morton
2020-12-16  4:47 ` [patch 94/95] mmap locking API: don't check locking if the mm isn't live yet Andrew Morton
2020-12-16  5:07   ` Jann Horn
2020-12-16 18:08     ` Jason Gunthorpe
2020-12-16  4:47 ` [patch 95/95] mm/gup: assert that the mmap lock is held in __get_user_pages() Andrew Morton

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=20201216044657.SBwU69OF0%akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=keescook@chromium.org \
    --cc=linux-mm@kvack.org \
    --cc=linux@roeck-us.net \
    --cc=mcroce@microsoft.com \
    --cc=mm-commits@vger.kernel.org \
    --cc=natechancellor@gmail.com \
    --cc=pasha.tatashin@soleen.com \
    --cc=pmladek@suse.com \
    --cc=rppt@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=tyhicks@linux.microsoft.com \
    /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;
as well as URLs for NNTP newsgroup(s).