All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Stephen Boyd <sboyd@kernel.org>,
	Guenter Roeck <linux@roeck-us.net>,
	Anna-Maria Gleixner <anna-maria@linutronix.de>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: [RFC][PATCH v3 01/33] timers: Add timer_shutdown_sync() and timer_shutdown() to be called before freeing timers
Date: Fri, 04 Nov 2022 01:40:54 -0400	[thread overview]
Message-ID: <20221104054912.063301453@goodmis.org> (raw)
In-Reply-To: 20221104054053.431922658@goodmis.org

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

We are hitting a common bug were a timer is being triggered after it is
freed. This causes a corruption in the timer link list and crashes the
kernel. Unfortunately it is not easy to know what timer it was that was
freed. Looking at the code, it appears that there are several cases that
del_timer() is used when del_timer_sync() should have been.

Add a timer_shutdown_sync() that not only does a del_timer_sync() but will mark
the timer as terminated in case it gets rearmed, it will trigger a WARN_ON. The
timer_shutdown_sync() is more likely to be used by developers that are about to
free a timer, then using del_timer_sync() as the latter is not as obvious
to being needed for freeing. Having the word "shutdown" in the name of the
function will hopefully help developers know that that function needs to
be called before freeing.

The added bonus is the marking of the timer as being freed such that it
will trigger a warning if it gets rearmed. At least that way if the system
crashes on a freed timer, at least we may see which timer it was that was
freed.

There's some situations that already know that the timer is shutdown and
does not need to perform the synchronization (or can not due to its
context). For these locations there's timer_shutdown() that only shuts
down the timer (prevents it from being rearmed) but does not add checks if
the timer is currently running.

This code is taken from Thomas Gleixner's "untested" version from my
original patch and modified after testing and with some other comments
from Linus addressed. As well as some extra comments added.

Link: https://lore.kernel.org/all/87pmlrkgi3.ffs@tglx/

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 .../RCU/Design/Requirements/Requirements.rst  |  2 +-
 Documentation/core-api/local_ops.rst          |  2 +-
 Documentation/kernel-hacking/locking.rst      |  5 ++
 include/linux/timer.h                         | 64 +++++++++++++++++--
 kernel/time/timer.c                           | 64 ++++++++++---------
 5 files changed, 98 insertions(+), 39 deletions(-)

diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
index a0f8164c8513..ec6de88846b9 100644
--- a/Documentation/RCU/Design/Requirements/Requirements.rst
+++ b/Documentation/RCU/Design/Requirements/Requirements.rst
@@ -1858,7 +1858,7 @@ unloaded. After a given module has been unloaded, any attempt to call
 one of its functions results in a segmentation fault. The module-unload
 functions must therefore cancel any delayed calls to loadable-module
 functions, for example, any outstanding mod_timer() must be dealt
-with via del_timer_sync() or similar.
+with via timer_shutdown_sync().
 
 Unfortunately, there is no way to cancel an RCU callback; once you
 invoke call_rcu(), the callback function is eventually going to be
diff --git a/Documentation/core-api/local_ops.rst b/Documentation/core-api/local_ops.rst
index 2ac3f9f29845..0b42ceaaf3c4 100644
--- a/Documentation/core-api/local_ops.rst
+++ b/Documentation/core-api/local_ops.rst
@@ -191,7 +191,7 @@ Here is a sample module which implements a basic per cpu counter using
 
     static void __exit test_exit(void)
     {
-            del_timer_sync(&test_timer);
+            timer_shutdown_sync(&test_timer);
     }
 
     module_init(test_init);
diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst
index 6805ae6e86e6..eb341b69fd15 100644
--- a/Documentation/kernel-hacking/locking.rst
+++ b/Documentation/kernel-hacking/locking.rst
@@ -1009,6 +1009,11 @@ use del_timer_sync() (``include/linux/timer.h``) to
 handle this case. It returns the number of times the timer had to be
 deleted before we finally stopped it from adding itself back in.
 
+Before freeing a timer, timer_shutdown() or timer_shutdown_sync() should be
+called which will keep it from being rearmed, although if it is rearmed, it
+will produce a warning.
+
+
 Locking Speed
 =============
 
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 648f00105f58..0758b447afd7 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -168,12 +168,45 @@ static inline int timer_pending(const struct timer_list * timer)
 	return !hlist_unhashed_lockless(&timer->entry);
 }
 
+extern int __del_timer(struct timer_list * timer, bool free);
+
 extern void add_timer_on(struct timer_list *timer, int cpu);
-extern int del_timer(struct timer_list * timer);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
 extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
 extern int timer_reduce(struct timer_list *timer, unsigned long expires);
 
+/**
+ * del_timer - deactivate a timer.
+ * @timer: the timer to be deactivated
+ *
+ * del_timer() deactivates a timer - this works on both active and inactive
+ * timers.
+ *
+ * The function returns whether it has deactivated a pending timer or not.
+ * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
+ * active timer returns 1.)
+ */
+static inline int del_timer(struct timer_list *timer)
+{
+	return __del_timer(timer, false);
+}
+
+/**
+ * timer_shutdown - deactivate a timer and shut it down
+ * @timer: the timer to be deactivated
+ *
+ * timer_shutdown() deactivates a timer - this works on both active
+ * and inactive timers, and will prevent it from being rearmed.
+ *
+ * The function returns whether it has deactivated a pending timer or not.
+ * (ie. timer_shutdown() of an inactive timer returns 0,
+ *   timer_shutdown() of an active timer returns 1.)
+ */
+static inline int timer_shutdown(struct timer_list *timer)
+{
+	return __del_timer(timer, true);
+}
+
 /*
  * The jiffies value which is added to now, when there is no timer
  * in the timer wheel:
@@ -183,14 +216,31 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires);
 extern void add_timer(struct timer_list *timer);
 
 extern int try_to_del_timer_sync(struct timer_list *timer);
+extern int __del_timer_sync(struct timer_list *timer, bool free);
 
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
-  extern int del_timer_sync(struct timer_list *timer);
-#else
-# define del_timer_sync(t)		del_timer(t)
-#endif
+static inline int del_timer_sync(struct timer_list *timer)
+{
+	return __del_timer_sync(timer, false);
+}
+
+/**
+ * timer_shutdown_sync - called before freeing the timer
+ * @timer: The timer to be freed
+ *
+ * Shutdown the timer before freeing. This will return when all pending timers
+ * have finished and it is safe to free the timer.
+ *
+ * Note, after calling this, if the timer is added back to the queue
+ * it will fail to be added and a WARNING will be triggered.
+ *
+ * Returns if it deactivated a pending timer or not.
+ */
+static inline int timer_shutdown_sync(struct timer_list *timer)
+{
+	return __del_timer_sync(timer, true);
+}
 
-#define del_singleshot_timer_sync(t) del_timer_sync(t)
+#define del_singleshot_timer_sync(t) timer_shutdown_sync(t)
 
 extern void init_timers(void);
 struct hrtimer;
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 717fcb9fb14a..7c224766065e 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1017,7 +1017,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option
 	unsigned int idx = UINT_MAX;
 	int ret = 0;
 
-	BUG_ON(!timer->function);
+	if (WARN_ON_ONCE(!timer->function))
+		return -EINVAL;
 
 	/*
 	 * This is a common optimization triggered by the networking code - if
@@ -1193,7 +1194,8 @@ EXPORT_SYMBOL(timer_reduce);
  */
 void add_timer(struct timer_list *timer)
 {
-	BUG_ON(timer_pending(timer));
+	if (WARN_ON_ONCE(timer_pending(timer)))
+		return;
 	__mod_timer(timer, timer->expires, MOD_TIMER_NOTPENDING);
 }
 EXPORT_SYMBOL(add_timer);
@@ -1210,7 +1212,8 @@ void add_timer_on(struct timer_list *timer, int cpu)
 	struct timer_base *new_base, *base;
 	unsigned long flags;
 
-	BUG_ON(timer_pending(timer) || !timer->function);
+	if (WARN_ON_ONCE(timer_pending(timer) || !timer->function))
+		return;
 
 	new_base = get_timer_cpu_base(timer->flags, cpu);
 
@@ -1237,18 +1240,7 @@ void add_timer_on(struct timer_list *timer, int cpu)
 }
 EXPORT_SYMBOL_GPL(add_timer_on);
 
-/**
- * del_timer - deactivate a timer.
- * @timer: the timer to be deactivated
- *
- * del_timer() deactivates a timer - this works on both active and inactive
- * timers.
- *
- * The function returns whether it has deactivated a pending timer or not.
- * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
- * active timer returns 1.)
- */
-int del_timer(struct timer_list *timer)
+int __del_timer(struct timer_list *timer, bool free)
 {
 	struct timer_base *base;
 	unsigned long flags;
@@ -1259,21 +1251,20 @@ int del_timer(struct timer_list *timer)
 	if (timer_pending(timer)) {
 		base = lock_timer_base(timer, &flags);
 		ret = detach_if_pending(timer, base, true);
+		if (free)
+			timer->function = NULL;
+		raw_spin_unlock_irqrestore(&base->lock, flags);
+	} else if (free) {
+		base = lock_timer_base(timer, &flags);
+		timer->function = NULL;
 		raw_spin_unlock_irqrestore(&base->lock, flags);
 	}
 
 	return ret;
 }
-EXPORT_SYMBOL(del_timer);
+EXPORT_SYMBOL(__del_timer);
 
-/**
- * try_to_del_timer_sync - Try to deactivate a timer
- * @timer: timer to delete
- *
- * This function tries to deactivate a timer. Upon successful (ret >= 0)
- * exit the timer is not queued and the handler is not running on any CPU.
- */
-int try_to_del_timer_sync(struct timer_list *timer)
+static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
 {
 	struct timer_base *base;
 	unsigned long flags;
@@ -1285,11 +1276,25 @@ int try_to_del_timer_sync(struct timer_list *timer)
 
 	if (base->running_timer != timer)
 		ret = detach_if_pending(timer, base, true);
+	if (free)
+		timer->function = NULL;
 
 	raw_spin_unlock_irqrestore(&base->lock, flags);
 
 	return ret;
 }
+
+/**
+ * try_to_del_timer_sync - Try to deactivate a timer
+ * @timer: timer to delete
+ *
+ * This function tries to deactivate a timer. Upon successful (ret >= 0)
+ * exit the timer is not queued and the handler is not running on any CPU.
+ */
+int try_to_del_timer_sync(struct timer_list *timer)
+{
+	return __try_to_del_timer_sync(timer, false);
+}
 EXPORT_SYMBOL(try_to_del_timer_sync);
 
 #ifdef CONFIG_PREEMPT_RT
@@ -1365,10 +1370,10 @@ static inline void timer_sync_wait_running(struct timer_base *base) { }
 static inline void del_timer_wait_running(struct timer_list *timer) { }
 #endif
 
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
 /**
- * del_timer_sync - deactivate a timer and wait for the handler to finish.
+ * __del_timer_sync - deactivate a timer and wait for the handler to finish.
  * @timer: the timer to be deactivated
+ * @free: Set to true if the timer is about to be freed
  *
  * This function only differs from del_timer() on SMP: besides deactivating
  * the timer it also makes sure the handler has finished executing on other
@@ -1402,7 +1407,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
  *
  * The function returns whether it has deactivated a pending timer or not.
  */
-int del_timer_sync(struct timer_list *timer)
+int __del_timer_sync(struct timer_list *timer, bool free)
 {
 	int ret;
 
@@ -1432,7 +1437,7 @@ int del_timer_sync(struct timer_list *timer)
 		lockdep_assert_preemption_enabled();
 
 	do {
-		ret = try_to_del_timer_sync(timer);
+		ret = __try_to_del_timer_sync(timer, free);
 
 		if (unlikely(ret < 0)) {
 			del_timer_wait_running(timer);
@@ -1442,8 +1447,7 @@ int del_timer_sync(struct timer_list *timer)
 
 	return ret;
 }
-EXPORT_SYMBOL(del_timer_sync);
-#endif
+EXPORT_SYMBOL(__del_timer_sync);
 
 static void call_timer_fn(struct timer_list *timer,
 			  void (*fn)(struct timer_list *),
-- 
2.35.1

  reply	other threads:[~2022-11-04  5:50 UTC|newest]

Thread overview: 134+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04  5:40 [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers Steven Rostedt
2022-11-04  5:40 ` [Bridge] " Steven Rostedt
2022-11-04  5:40 ` Steven Rostedt
2022-11-04  5:40 ` [Intel-wired-lan] " Steven Rostedt
2022-11-04  5:40 ` [Intel-gfx] " Steven Rostedt
2022-11-04  5:40 ` Steven Rostedt
2022-11-04  5:40 ` Steven Rostedt [this message]
2022-11-04  5:40 ` [RFC][PATCH v3 02/33] timers: s390/cmm: Use timer_shutdown_sync() before freeing timer Steven Rostedt
2022-11-04  5:40 ` [RFC][PATCH v3 03/33] timers: sh: " Steven Rostedt
2022-11-04  5:40 ` [RFC][PATCH v3 04/33] timers: block: " Steven Rostedt
2022-11-04  5:56   ` Steven Rostedt
2022-11-04  5:56     ` Steven Rostedt
2022-11-04  5:40 ` [RFC][PATCH v3 05/33] timers: ACPI: " Steven Rostedt
2022-11-07 15:47   ` Jarkko Sakkinen
2022-11-04  5:40 ` [RFC][PATCH v3 06/33] timers: atm: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 07/33] timers: PM: Use timer_shutdown_sync() Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 08/33] timers: Bluetooth: Use timer_shutdown_sync() before freeing timer Steven Rostedt
2022-11-04  7:18   ` timers: Use timer_shutdown*() before freeing timers bluez.test.bot
2022-11-18  3:51   ` bluez.test.bot
2022-11-18  4:38   ` bluez.test.bot
2022-11-18  5:29   ` bluez.test.bot
2022-11-18  6:34   ` bluez.test.bot
2022-11-18  7:29   ` bluez.test.bot
2022-11-18  8:33   ` bluez.test.bot
2022-11-18  9:30   ` bluez.test.bot
2022-11-19  3:56   ` bluez.test.bot
2022-11-19  5:04   ` bluez.test.bot
2022-11-04  5:41 ` [RFC][PATCH v3 09/33] timers: hangcheck: Use timer_shutdown_sync() before freeing timer Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 10/33] timers: ipmi: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 11/33] random: use " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 12/33] timers: dma-buf: Use " Steven Rostedt
2022-11-04  5:54   ` Steven Rostedt
2022-11-04  5:54     ` Steven Rostedt
2022-11-04  7:15     ` Christian König
2022-11-04  7:15       ` Christian König
2022-11-04 18:58       ` Steven Rostedt
2022-11-04 18:58         ` Steven Rostedt
2022-11-05  8:12         ` [Linaro-mm-sig] " Christian König
2022-11-05  8:12           ` Christian König
2022-11-04  5:41 ` [RFC][PATCH v3 13/33] timers: drm: " Steven Rostedt
2022-11-04  5:41   ` [Intel-gfx] " Steven Rostedt
2022-11-04  5:55   ` Steven Rostedt
2022-11-04  5:55     ` Steven Rostedt
2022-11-04  5:55     ` [Intel-gfx] " Steven Rostedt
2022-11-04  8:48   ` Tvrtko Ursulin
2022-11-04  8:48     ` [Intel-gfx] " Tvrtko Ursulin
2022-11-04  8:48     ` Tvrtko Ursulin
2022-11-04 19:02     ` Steven Rostedt
2022-11-04 19:02       ` [Intel-gfx] " Steven Rostedt
2022-11-04 19:02       ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 14/33] timers: HID: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 16/33] timers: mISDN: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 17/33] timers: leds: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 18/33] timers: media: " Steven Rostedt
2022-11-04  5:57   ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 19/33] timers: net: " Steven Rostedt
2022-11-04  5:41   ` [Bridge] " Steven Rostedt
2022-11-04  5:41   ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 20/33] timers: usb: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 21/33] timers: cgroup: " Steven Rostedt
2022-11-04  5:41   ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 22/33] timers: workqueue: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 23/33] timers: nfc: pn533: " Steven Rostedt
2022-11-04 15:46   ` Krzysztof Kozlowski
2022-11-05  5:25     ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 24/33] timers: pcmcia: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 25/33] timers: scsi: Use timer_shutdown_sync() and timer_shutdown() " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 26/33] timers: tty: Use timer_shutdown_sync() " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 27/33] timers: ext4: " Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 28/33] timers: fs/nilfs2: " Steven Rostedt
2022-11-04  5:41   ` Steven Rostedt
2022-11-04  6:57   ` Ryusuke Konishi
2022-11-04  6:57     ` Ryusuke Konishi
2022-11-04 18:54     ` Steven Rostedt
2022-11-04 18:54       ` Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 29/33] timers: ALSA: " Steven Rostedt
2022-11-04  5:41   ` Steven Rostedt
2022-11-04  8:11   ` Takashi Iwai
2022-11-04  8:11     ` Takashi Iwai
2022-11-04  5:41 ` [RFC][PATCH v3 30/33] timers: jbd2: Use timer_shutdown() " Steven Rostedt
2022-11-07 12:37   ` Jan Kara
2022-11-04  5:41 ` [RFC][PATCH v3 31/33] timers: sched/psi: Use timer_shutdown_sync() " Steven Rostedt
2022-11-04 20:11   ` Johannes Weiner
2022-11-04 20:29     ` Suren Baghdasaryan
2022-11-04  5:41 ` [RFC][PATCH v3 32/33] timers: x86/mce: Use __init_timer() for resetting timers Steven Rostedt
2022-11-04  5:41 ` [RFC][PATCH v3 33/33] timers: Expand DEBUG_OBJECTS_TIMER to check if it ever was used Steven Rostedt
2022-11-04 17:00 ` [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers Linus Torvalds
2022-11-04 17:00   ` [Bridge] " Linus Torvalds
2022-11-04 17:00   ` Linus Torvalds
2022-11-04 17:00   ` Linus Torvalds
2022-11-04 17:00   ` [Intel-wired-lan] " Linus Torvalds
2022-11-04 17:00   ` [Intel-gfx] " Linus Torvalds
2022-11-04 19:22 ` Guenter Roeck
2022-11-04 19:22   ` [Bridge] " Guenter Roeck
2022-11-04 19:22   ` Guenter Roeck
2022-11-04 19:22   ` [Intel-wired-lan] " Guenter Roeck
2022-11-04 19:22   ` [Intel-gfx] " Guenter Roeck
2022-11-04 19:22   ` Guenter Roeck
2022-11-04 19:42   ` Steven Rostedt
2022-11-04 19:42     ` [Bridge] " Steven Rostedt
2022-11-04 19:42     ` Steven Rostedt
2022-11-04 19:42     ` [Intel-wired-lan] " Steven Rostedt
2022-11-04 19:42     ` [Intel-gfx] " Steven Rostedt
2022-11-04 19:42     ` Steven Rostedt
2022-11-04 19:50     ` Linus Torvalds
2022-11-04 19:50       ` [Bridge] " Linus Torvalds
2022-11-04 19:50       ` Linus Torvalds
2022-11-04 19:50       ` [Intel-wired-lan] " Linus Torvalds
2022-11-04 19:50       ` [Intel-gfx] " Linus Torvalds
2022-11-04 19:50       ` Linus Torvalds
2022-11-04 20:38     ` Steven Rostedt
2022-11-04 20:38       ` [Bridge] " Steven Rostedt
2022-11-04 20:38       ` Steven Rostedt
2022-11-04 20:38       ` [Intel-wired-lan] " Steven Rostedt
2022-11-04 20:38       ` [Intel-gfx] " Steven Rostedt
2022-11-04 20:38       ` Steven Rostedt
2022-11-04 20:42       ` Guenter Roeck
2022-11-04 20:42         ` [Bridge] " Guenter Roeck
2022-11-04 20:42         ` Guenter Roeck
2022-11-04 20:42         ` Guenter Roeck
2022-11-04 20:42         ` [Intel-wired-lan] " Guenter Roeck
2022-11-04 20:42         ` [Intel-gfx] " Guenter Roeck
2022-11-04 20:41     ` Guenter Roeck
2022-11-04 20:41       ` [Bridge] " Guenter Roeck
2022-11-04 20:41       ` Guenter Roeck
2022-11-04 20:41       ` [Intel-wired-lan] " Guenter Roeck
2022-11-04 20:41       ` [Intel-gfx] " Guenter Roeck
2022-11-04 20:41       ` Guenter Roeck
2022-11-04 23:34 ` Guenter Roeck
2022-11-04 23:34   ` [Bridge] " Guenter Roeck
2022-11-04 23:34   ` Guenter Roeck
2022-11-04 23:34   ` [Intel-wired-lan] " Guenter Roeck
2022-11-04 23:34   ` [Intel-gfx] " Guenter Roeck
2022-11-04 23:34   ` Guenter Roeck

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=20221104054912.063301453@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=anna-maria@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=sboyd@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.