linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Bristot de Oliveira <bristot@kernel.org>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Daniel Bristot de Oliveira <bristot@kernel.org>,
	Jonathan Corbet <corbet@lwn.net>, Ingo Molnar <mingo@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Will Deacon <will@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Marco Elver <elver@google.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Gabriele Paoloni <gpaoloni@redhat.com>,
	Juri Lelli <juri.lelli@redhat.com>,
	Clark Williams <williams@redhat.com>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-trace-devel@vger.kernel.org,
	Wim Van Sebroeck <wim@linux-watchdog.org>,
	Guenter Roeck <linux@roeck-us.net>
Subject: [RFC V2 19/21] rv/monitor: Add safe watchdog nowayout monitor
Date: Mon, 14 Feb 2022 11:45:10 +0100	[thread overview]
Message-ID: <7a810f46b6136565a364001e7d1550fb9a4ccf62.1644830251.git.bristot@kernel.org> (raw)
In-Reply-To: <cover.1644830251.git.bristot@kernel.org>

This is a simplification of the safe_wtd monitor, named safe_wtd_nwo.
The difference between these two monitors is that the latter enforces
the nowayout watchdog device option before opening the watchdog.

In this way, once the watchdog is starts, the watchdog hardware will
serve as an safety-monitor until the system shutdown.

For further information, please refer to:
        Documentation/trace/rv/watchdog-monitor.rst

The monitor specification was developed together with Gabriele Paoloni,
in the context of the Linux Foundation Elisa Project.

Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marco Elver <elver@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Gabriele Paoloni <gpaoloni@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-trace-devel@vger.kernel.org
Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org>
---
 kernel/trace/rv/Kconfig                       |  10 +
 kernel/trace/rv/Makefile                      |   1 +
 kernel/trace/rv/monitor_safe_wtd_nwo/model.h  |  61 ++++
 .../rv/monitor_safe_wtd_nwo/safe_wtd_nwo.c    | 309 ++++++++++++++++++
 .../rv/monitor_safe_wtd_nwo/safe_wtd_nwo.h    |  64 ++++
 5 files changed, 445 insertions(+)
 create mode 100644 kernel/trace/rv/monitor_safe_wtd_nwo/model.h
 create mode 100644 kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.c
 create mode 100644 kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.h

diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig
index 93b36f215b2b..7e797e132f60 100644
--- a/kernel/trace/rv/Kconfig
+++ b/kernel/trace/rv/Kconfig
@@ -39,6 +39,16 @@ config RV_MON_SAFE_WTD
 	  For futher information see:
 	    Documentation/trace/rv/safety-monitor.rst
 
+config RV_MON_SAFE_WTD_NWO
+	tristate "Safety watchdog nowayout"
+	help
+	  Enable safe_wtd_nwo, this monitor observes the interaction
+	  between a user-space safety monitor and a watchdog device. It
+	  enforces the usage of watchdog's nowayout config.
+
+	  For futher information see:
+	    Documentation/trace/rv/safety-monitor.rst
+
 config RV_REACTORS
 	bool "Runtime verification reactors"
 	default y if RV
diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile
index 854d0f6e453b..44277103d178 100644
--- a/kernel/trace/rv/Makefile
+++ b/kernel/trace/rv/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_RV) += rv.o
 obj-$(CONFIG_RV_MON_WIP) += monitor_wip/wip.o
 obj-$(CONFIG_RV_MON_WWNR) += monitor_wwnr/wwnr.o
 obj-$(CONFIG_RV_MON_SAFE_WTD) += monitor_safe_wtd/safe_wtd.o
+obj-$(CONFIG_RV_MON_SAFE_WTD_NWO) += monitor_safe_wtd_nwo/safe_wtd_nwo.o
 obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
 obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
 obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o
diff --git a/kernel/trace/rv/monitor_safe_wtd_nwo/model.h b/kernel/trace/rv/monitor_safe_wtd_nwo/model.h
new file mode 100644
index 000000000000..504a93e35b93
--- /dev/null
+++ b/kernel/trace/rv/monitor_safe_wtd_nwo/model.h
@@ -0,0 +1,61 @@
+enum states_safe_wtd_nwo {
+	init = 0,
+	closed_running,
+	nwo,
+	opened,
+	safe,
+	set,
+	started,
+	state_max
+};
+
+enum events_safe_wtd_nwo {
+	close = 0,
+	nowayout,
+	open,
+	other_threads,
+	ping,
+	set_safe_timeout,
+	start,
+	event_max
+};
+
+struct automaton_safe_wtd_nwo {
+	char *state_names[state_max];
+	char *event_names[event_max];
+	char function[state_max][event_max];
+	char initial_state;
+	char final_states[state_max];
+};
+
+struct automaton_safe_wtd_nwo automaton_safe_wtd_nwo = {
+	.state_names = {
+		"init",
+		"closed_running",
+		"nwo",
+		"opened",
+		"safe",
+		"set",
+		"started"
+	},
+	.event_names = {
+		"close",
+		"nowayout",
+		"open",
+		"other_threads",
+		"ping",
+		"set_safe_timeout",
+		"start"
+	},
+	.function = {
+		{             -1,            nwo,             -1,             -1,             -1,             -1,             -1 },
+		{             -1, closed_running,        started, closed_running,             -1,             -1,             -1 },
+		{             -1,            nwo,         opened,            nwo,             -1,             -1,             -1 },
+		{            nwo,             -1,             -1,             -1,             -1,             -1,        started },
+		{ closed_running,             -1,             -1,             -1,           safe,             -1,             -1 },
+		{             -1,             -1,             -1,             -1,           safe,             -1,             -1 },
+		{ closed_running,             -1,             -1,             -1,             -1,            set,             -1 },
+	},
+	.initial_state = init,
+	.final_states = { 1, 0, 0, 0, 0, 0, 0 },
+};
diff --git a/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.c b/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.c
new file mode 100644
index 000000000000..e19e10da0dc1
--- /dev/null
+++ b/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.c
@@ -0,0 +1,309 @@
+#include <linux/ftrace.h>
+#include <linux/tracepoint.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rv.h>
+#include <rv/da_monitor.h>
+
+#include <linux/watchdog.h>
+#include <linux/moduleparam.h>
+
+#define MODULE_NAME "safe_wtd_nwo"
+
+/*
+ * This is the self-generated part of the monitor. Generally, there is no need
+ * to touch this section.
+ */
+#include "model.h"
+
+/*
+ * Declare the deterministic automata monitor.
+ *
+ * The rv monitor reference is needed for the monitor declaration.
+ */
+struct rv_monitor rv_safe_wtd_nwo;
+DECLARE_DA_MON_GLOBAL(safe_wtd_nwo, char);
+
+#define CREATE_TRACE_POINTS
+#include "safe_wtd_nwo.h"
+
+/*
+ * custom: safe_timeout is the maximum value a watchdog monitor
+ * can set. This value is registered here to duplicate the information.
+ * In this way, a miss-behaving monitor can be detected.
+ */
+static int safe_timeout = ~0;
+module_param(safe_timeout, int, 0444);
+
+/*
+ * custom: if check_timeout is set, the monitor will check if the time left
+ * in the watchdog is less than or equals to the last safe timeout set by
+ * user-space. This check is done after each ping. In this way, if any
+ * code by-passed the watchdog dev interface setting a higher (so unsafe)
+ * timeout, this monitor will catch the side effect and react.
+ */
+static int last_timeout_set = 0;
+static int check_timeout = 0;
+module_param(check_timeout, int, 0444);
+
+/*
+ * custom: if dont_stop is set the monitor will react if stopped.
+ */
+static int dont_stop = 0;
+module_param(dont_stop, int, 0444);
+
+/*
+ * custom: there are some states that are kept after the watchdog is closed.
+ * For example, the nowayout state.
+ *
+ * Thus, the RV monitor needs to keep track of these states after a start/stop
+ * of the RV monitor itself, and should not reset after each restart - keeping the
+ * know state until the system shutdown.
+ *
+ * If for an unknown reason an RV monitor would like to reset the RV monitor at each
+ * RV monitor start, set it to one.
+ */
+static int reset_on_restart = 0;
+module_param(reset_on_restart, int, 0444);
+
+/*
+ * open_pid takes note of the first thread that opened the watchdog.
+ *
+ * Any other thread that generates an event will cause an "other_threads"
+ * event in the monitor.
+ */
+static int open_pid = 0;
+
+/*
+ * watchdog_id: the watchdog to monitor
+ */
+static int watchdog_id = 0;
+module_param(watchdog_id, int, 0444);
+
+static void handle_nowayout(void *data, struct watchdog_device *wdd)
+{
+	if (wdd->id != watchdog_id)
+		return;
+
+	da_handle_init_run_event_safe_wtd_nwo(nowayout);
+}
+
+static void handle_close(void *data, struct watchdog_device *wdd)
+{
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+	} else {
+		da_handle_event_safe_wtd_nwo(close);
+		open_pid = 0;
+	}
+}
+
+static void handle_open(void *data, struct watchdog_device *wdd)
+{
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+	} else {
+		da_handle_init_run_event_safe_wtd_nwo(open);
+		open_pid = current->pid;
+	}
+}
+
+static void blocked_events(void *data, struct watchdog_device *wdd)
+{
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+		return;
+	}
+	da_handle_event_safe_wtd_nwo(other_threads);
+}
+
+static void handle_ping(void *data, struct watchdog_device *wdd)
+{
+	char msg[128];
+	unsigned int timeout;
+
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+		return;
+	}
+
+	da_handle_event_safe_wtd_nwo(ping);
+
+	if (!check_timeout)
+		return;
+
+	if (wdd->ops->get_timeleft) {
+		timeout = wdd->ops->get_timeleft(wdd);
+		if (timeout > last_timeout_set) {
+			snprintf(msg, 128,
+				 "watchdog timout is %u > than previously set (%d)\n",
+				 timeout, last_timeout_set);
+			cond_react(msg);
+		}
+	} else {
+		snprintf(msg, 128, "error getting timeout: option not supported\n");
+		cond_react(msg);
+	}
+}
+
+static void handle_set_safe_timeout(void *data, struct watchdog_device *wdd, unsigned long timeout)
+{
+	char msg[128];
+
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+		return;
+	}
+
+	da_handle_event_safe_wtd_nwo(set_safe_timeout);
+
+	if (timeout > safe_timeout) {
+		snprintf(msg, 128, "set safety timeout is too high: %d", (int) timeout);
+		cond_react(msg);
+	}
+
+	if (check_timeout)
+		last_timeout_set = timeout;
+}
+
+static void handle_start(void *data, struct watchdog_device *wdd)
+{
+	if (wdd->id != watchdog_id)
+		return;
+
+	if (open_pid && current->pid != open_pid) {
+		da_handle_init_run_event_safe_wtd_nwo(other_threads);
+		return;
+	}
+
+	da_handle_event_safe_wtd_nwo(start);
+}
+
+#define NR_TP	9
+static struct tracepoint_hook_helper tracepoints_to_hook[NR_TP] = {
+	{
+		.probe = handle_close,
+		.name = "watchdog_close",
+		.registered = 0
+	},
+	{
+		.probe = handle_nowayout,
+		.name = "watchdog_nowayout",
+		.registered = 0
+	},
+	{
+		.probe = handle_open,
+		.name = "watchdog_open",
+		.registered = 0
+	},
+	{
+		.probe = handle_ping,
+		.name = "watchdog_ping",
+		.registered = 0
+	},
+	{
+		.probe = handle_set_safe_timeout,
+		.name = "watchdog_set_timeout",
+		.registered = 0
+	},
+	{
+		.probe = handle_start,
+		.name = "watchdog_start",
+		.registered = 0
+	},
+	{
+		.probe = blocked_events,
+		.name = "watchdog_stop",
+		.registered = 0
+	},
+	{
+		.probe = blocked_events,
+		.name = "watchdog_set_keep_alive",
+		.registered = 0
+	},
+	{
+		.probe = blocked_events,
+		.name = "watchdog_keep_alive",
+		.registered = 0
+	},
+};
+
+static int mon_started = 0;
+
+static int start_safe_wtd_nwo(void)
+{
+	int retval;
+
+	if (!mon_started || reset_on_restart) {
+		da_monitor_init_safe_wtd_nwo();
+		mon_started = 1;
+	}
+
+	retval = thh_hook_probes(tracepoints_to_hook, NR_TP);
+	if (retval)
+		goto out_err;
+
+	return 0;
+
+out_err:
+	return -EINVAL;
+}
+
+static void stop_safe_wtd_nwo(void)
+{
+	if (dont_stop)
+		cond_react("dont_stop safe_wtd_nwo is set.");
+
+	rv_safe_wtd_nwo.enabled = 0;
+	thh_unhook_probes(tracepoints_to_hook, NR_TP);
+	return;
+}
+
+/*
+ * This is the monitor register section.
+ */
+struct rv_monitor rv_safe_wtd_nwo = {
+	.name = "safe_wtd_nwo",
+	.description = "A watchdog monitor guarding a safety monitor actions, nowayout required.",
+	.start = start_safe_wtd_nwo,
+	.stop = stop_safe_wtd_nwo,
+	.reset = da_monitor_reset_all_safe_wtd_nwo,
+	.enabled = 0,
+};
+
+int register_safe_wtd_nwo(void)
+{
+	rv_register_monitor(&rv_safe_wtd_nwo);
+	return 0;
+}
+
+void unregister_safe_wtd_nwo(void)
+{
+	if (rv_safe_wtd_nwo.enabled)
+		stop_safe_wtd_nwo();
+
+	rv_unregister_monitor(&rv_safe_wtd_nwo);
+}
+
+module_init(register_safe_wtd_nwo);
+module_exit(unregister_safe_wtd_nwo);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Daniel Bristot de Oliveira <bristot@kernel.org>");
+MODULE_DESCRIPTION("Safe watchdog RV monitor nowayout");
diff --git a/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.h b/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.h
new file mode 100644
index 000000000000..0d33800b0972
--- /dev/null
+++ b/kernel/trace/rv/monitor_safe_wtd_nwo/safe_wtd_nwo.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rv
+
+#if !defined(_SAFETY_MONITOR_NWO_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _SAFETY_MONITOR_NWO_TRACE_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(event_safe_wtd_nwo,
+
+	TP_PROTO(char state, char event, char next_state, bool safe),
+
+	TP_ARGS(state, event, next_state, safe),
+
+	TP_STRUCT__entry(
+		__field(	char,		state		)
+		__field(	char,		event		)
+		__field(	char,		next_state	)
+		__field(	bool,		safe		)
+	),
+
+	TP_fast_assign(
+		__entry->state = state;
+		__entry->event = event;
+		__entry->next_state = next_state;
+		__entry->safe = safe;
+	),
+
+	TP_printk("%s x %s -> %s %s",
+		model_get_state_name_safe_wtd_nwo(__entry->state),
+		model_get_event_name_safe_wtd_nwo(__entry->event),
+		model_get_state_name_safe_wtd_nwo(__entry->next_state),
+		__entry->safe ? "(safe)" : "")
+);
+
+TRACE_EVENT(error_safe_wtd_nwo,
+
+	TP_PROTO(char state, char event),
+
+	TP_ARGS(state, event),
+
+	TP_STRUCT__entry(
+		__field(	char,		state		)
+		__field(	char,		event		)
+	),
+
+	TP_fast_assign(
+		__entry->state = state;
+		__entry->event = event;
+	),
+
+	TP_printk("event %s not expected in the state %s",
+		model_get_event_name_safe_wtd_nwo(__entry->event),
+		model_get_state_name_safe_wtd_nwo(__entry->state))
+);
+
+#endif /* _SAFETY_MONITOR_NWO_H */
+
+/* This part ust be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../kernel/trace/rv/monitor_safe_wtd_nwo/
+#define TRACE_INCLUDE_FILE safe_wtd_nwo
+#include <trace/define_trace.h>
-- 
2.33.1


  parent reply	other threads:[~2022-02-14 11:24 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-14 10:44 [RFC V2 00/21] The Runtime Verification (RV) interface Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 01/21] rv: Add " Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 02/21] rv: Add runtime reactors interface Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 03/21] rv/include: Add helper functions for deterministic automata Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 04/21] rv/include: Add deterministic automata monitor definition via C macros Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 05/21] rv/include: Add tracing helper functions Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 06/21] tools/rv: Add dot2c Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 07/21] tools/rv: Add dot2k Daniel Bristot de Oliveira
2022-02-14 10:44 ` [RFC V2 08/21] rv/monitor: Add the wip monitor skeleton created by dot2k Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 09/21] rv/monitor: wip instrumentation and Makefile/Kconfig entries Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 10/21] rv/monitor: Add the wwnr monitor skeleton created by dot2k Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 11/21] rv/monitor: wwnr instrumentation and Makefile/Kconfig entries Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 12/21] rv/reactor: Add the printk reactor Daniel Bristot de Oliveira
2022-02-14 17:25   ` Shuah Khan
2022-02-14 18:06     ` Daniel Bristot de Oliveira
2022-02-15 10:03       ` John Ogness
2022-02-15 12:43         ` Daniel Bristot de Oliveira
2022-02-15 13:33           ` John Ogness
2022-02-15 17:21             ` Daniel Bristot de Oliveira
2022-02-15 19:33               ` John Ogness
2022-02-16  8:58                 ` Daniel Bristot de Oliveira
2022-02-16 10:51                   ` John Ogness
2022-02-16 13:19                     ` Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 13/21] rv/reactor: Add the panic reactor Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 14/21] Documentation/rv: Add a basic documentation Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 15/21] Documentation/rv: Add deterministic automata monitor synthesis documentation Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 16/21] Documentation/rv: Add deterministic automata instrumentation documentation Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 17/21] watchdog/dev: Add tracepoints Daniel Bristot de Oliveira
2022-02-14 14:57   ` Guenter Roeck
2022-02-14 15:39     ` Daniel Bristot de Oliveira
2022-02-16 16:01   ` Peter.Enderborg
2022-02-17 16:27     ` Daniel Bristot de Oliveira
2022-02-17 17:27       ` Guenter Roeck
2022-02-17 17:49         ` Gabriele Paoloni
2022-02-17 17:56           ` Daniel Bristot de Oliveira
2022-02-17 18:17           ` Guenter Roeck
2022-02-17 18:32             ` Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 18/21] rv/monitor: Add safe watchdog monitor Daniel Bristot de Oliveira
2022-02-14 10:45 ` Daniel Bristot de Oliveira [this message]
2022-02-14 10:45 ` [RFC V2 20/21] rv/safety_app: Add an safety_app sample Daniel Bristot de Oliveira
2022-02-14 10:45 ` [RFC V2 21/21] Documentation/rv: Add watchdog-monitor documentation Daniel Bristot de Oliveira

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=7a810f46b6136565a364001e7d1550fb9a4ccf62.1644830251.git.bristot@kernel.org \
    --to=bristot@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=corbet@lwn.net \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=gpaoloni@redhat.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=mingo@redhat.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=skhan@linuxfoundation.org \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    --cc=williams@redhat.com \
    --cc=wim@linux-watchdog.org \
    /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).