]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Oct 2025 11:13:15 +0000 (13:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Oct 2025 11:13:15 +0000 (13:13 +0200)
added patches:
arm-spear-do-not-use-timer-namespace-for-timer_shutdown-function.patch
bluetooth-hci_qca-fix-the-teardown-problem-for-real.patch
clocksource-drivers-arm_arch_timer-do-not-use-timer-namespace-for-timer_shutdown-function.patch
clocksource-drivers-sp804-do-not-use-timer-namespace-for-timer_shutdown-function.patch
documentation-remove-bogus-claim-about-del_timer_sync.patch
documentation-replace-del_timer-del_timer_sync.patch
timers-add-shutdown-mechanism-to-the-internal-functions.patch
timers-provide-timer_shutdown.patch
timers-replace-bug_on-s.patch
timers-silently-ignore-timers-with-a-null-function.patch
timers-split-del_timer-to-prepare-for-shutdown-mode.patch
timers-update-the-documentation-to-reflect-on-the-new-timer_shutdown-api.patch

13 files changed:
queue-6.1/arm-spear-do-not-use-timer-namespace-for-timer_shutdown-function.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_qca-fix-the-teardown-problem-for-real.patch [new file with mode: 0644]
queue-6.1/clocksource-drivers-arm_arch_timer-do-not-use-timer-namespace-for-timer_shutdown-function.patch [new file with mode: 0644]
queue-6.1/clocksource-drivers-sp804-do-not-use-timer-namespace-for-timer_shutdown-function.patch [new file with mode: 0644]
queue-6.1/documentation-remove-bogus-claim-about-del_timer_sync.patch [new file with mode: 0644]
queue-6.1/documentation-replace-del_timer-del_timer_sync.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functions.patch [new file with mode: 0644]
queue-6.1/timers-provide-timer_shutdown.patch [new file with mode: 0644]
queue-6.1/timers-replace-bug_on-s.patch [new file with mode: 0644]
queue-6.1/timers-silently-ignore-timers-with-a-null-function.patch [new file with mode: 0644]
queue-6.1/timers-split-del_timer-to-prepare-for-shutdown-mode.patch [new file with mode: 0644]
queue-6.1/timers-update-the-documentation-to-reflect-on-the-new-timer_shutdown-api.patch [new file with mode: 0644]

diff --git a/queue-6.1/arm-spear-do-not-use-timer-namespace-for-timer_shutdown-function.patch b/queue-6.1/arm-spear-do-not-use-timer-namespace-for-timer_shutdown-function.patch
new file mode 100644 (file)
index 0000000..5659e62
--- /dev/null
@@ -0,0 +1,75 @@
+From stable+bounces-184010-greg=kroah.com@vger.kernel.org Fri Oct 10 17:03:38 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:42 +0900
+Subject: ARM: spear: Do not use timer namespace for timer_shutdown() function
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-3-aha310510@gmail.com>
+
+From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
+
+[ Upstream commit 80b55772d41d8afec68dbc4ff0368a9fe5d1f390 ]
+
+A new "shutdown" timer state is being added to the generic timer code. One
+of the functions to change the timer into the state is called
+"timer_shutdown()". This means that there can not be other functions called
+"timer_shutdown()" as the timer code owns the "timer_*" name space.
+
+Rename timer_shutdown() to spear_timer_shutdown() to avoid this conflict.
+
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://lkml.kernel.org/r/20221106212701.822440504@goodmis.org
+Link: https://lore.kernel.org/all/20221105060155.228348078@goodmis.org/
+Link: https://lore.kernel.org/r/20221110064146.810953418@goodmis.org
+Link: https://lore.kernel.org/r/20221123201624.513863211@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-spear/time.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/mach-spear/time.c
++++ b/arch/arm/mach-spear/time.c
+@@ -90,7 +90,7 @@ static void __init spear_clocksource_ini
+               200, 16, clocksource_mmio_readw_up);
+ }
+-static inline void timer_shutdown(struct clock_event_device *evt)
++static inline void spear_timer_shutdown(struct clock_event_device *evt)
+ {
+       u16 val = readw(gpt_base + CR(CLKEVT));
+@@ -101,7 +101,7 @@ static inline void timer_shutdown(struct
+ static int spear_shutdown(struct clock_event_device *evt)
+ {
+-      timer_shutdown(evt);
++      spear_timer_shutdown(evt);
+       return 0;
+ }
+@@ -111,7 +111,7 @@ static int spear_set_oneshot(struct cloc
+       u16 val;
+       /* stop the timer */
+-      timer_shutdown(evt);
++      spear_timer_shutdown(evt);
+       val = readw(gpt_base + CR(CLKEVT));
+       val |= CTRL_ONE_SHOT;
+@@ -126,7 +126,7 @@ static int spear_set_periodic(struct clo
+       u16 val;
+       /* stop the timer */
+-      timer_shutdown(evt);
++      spear_timer_shutdown(evt);
+       period = clk_get_rate(gpt_clk) / HZ;
+       period >>= CTRL_PRESCALER16;
diff --git a/queue-6.1/bluetooth-hci_qca-fix-the-teardown-problem-for-real.patch b/queue-6.1/bluetooth-hci_qca-fix-the-teardown-problem-for-real.patch
new file mode 100644 (file)
index 0000000..06ebc56
--- /dev/null
@@ -0,0 +1,78 @@
+From aha310510@gmail.com Fri Oct 10 17:03:58 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:52 +0900
+Subject: Bluetooth: hci_qca: Fix the teardown problem for real
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-13-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit e0d3da982c96aeddc1bbf1cf9469dbb9ebdca657 ]
+
+While discussing solutions for the teardown problem which results from
+circular dependencies between timers and workqueues, where timers schedule
+work from their timer callback and workqueues arm the timers from work
+items, it was discovered that the recent fix to the QCA code is incorrect.
+
+That commit fixes the obvious problem of using del_timer() instead of
+del_timer_sync() and reorders the teardown calls to
+
+   destroy_workqueue(wq);
+   del_timer_sync(t);
+
+This makes it less likely to explode, but it's still broken:
+
+   destroy_workqueue(wq);
+   /* After this point @wq cannot be touched anymore */
+
+   ---> timer expires
+         queue_work(wq) <---- Results in a NULL pointer dereference
+                             deep in the work queue core code.
+   del_timer_sync(t);
+
+Use the new timer_shutdown_sync() function to ensure that the timers are
+disarmed, no timer callbacks are running and the timers cannot be armed
+again. This restores the original teardown sequence:
+
+   timer_shutdown_sync(t);
+   destroy_workqueue(wq);
+
+which is now correct because the timer core silently ignores potential
+rearming attempts which can happen when destroy_workqueue() drains pending
+work before mopping up the workqueue.
+
+Fixes: 72ef98445aca ("Bluetooth: hci_qca: Use del_timer_sync() before freeing")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Acked-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
+Link: https://lore.kernel.org/all/87iljhsftt.ffs@tglx
+Link: https://lore.kernel.org/r/20221123201625.435907114@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -710,9 +710,15 @@ static int qca_close(struct hci_uart *hu
+       skb_queue_purge(&qca->tx_wait_q);
+       skb_queue_purge(&qca->txq);
+       skb_queue_purge(&qca->rx_memdump_q);
++      /*
++       * Shut the timers down so they can't be rearmed when
++       * destroy_workqueue() drains pending work which in turn might try
++       * to arm a timer.  After shutdown rearm attempts are silently
++       * ignored by the timer core code.
++       */
++      timer_shutdown_sync(&qca->tx_idle_timer);
++      timer_shutdown_sync(&qca->wake_retrans_timer);
+       destroy_workqueue(qca->workqueue);
+-      del_timer_sync(&qca->tx_idle_timer);
+-      del_timer_sync(&qca->wake_retrans_timer);
+       qca->hu = NULL;
+       kfree_skb(qca->rx_skb);
diff --git a/queue-6.1/clocksource-drivers-arm_arch_timer-do-not-use-timer-namespace-for-timer_shutdown-function.patch b/queue-6.1/clocksource-drivers-arm_arch_timer-do-not-use-timer-namespace-for-timer_shutdown-function.patch
new file mode 100644 (file)
index 0000000..2f0006b
--- /dev/null
@@ -0,0 +1,76 @@
+From aha310510@gmail.com Fri Oct 10 17:03:15 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:43 +0900
+Subject: clocksource/drivers/arm_arch_timer: Do not use timer namespace for timer_shutdown() function
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-4-aha310510@gmail.com>
+
+From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
+
+[ Upstream commit 73737a5833ace25a8408b0d3b783637cb6bf29d1 ]
+
+A new "shutdown" timer state is being added to the generic timer code. One
+of the functions to change the timer into the state is called
+"timer_shutdown()". This means that there can not be other functions
+called "timer_shutdown()" as the timer code owns the "timer_*" name space.
+
+Rename timer_shutdown() to arch_timer_shutdown() to avoid this conflict.
+
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Link: https://lkml.kernel.org/r/20221106212702.002251651@goodmis.org
+Link: https://lore.kernel.org/all/20221105060155.409832154@goodmis.org/
+Link: https://lore.kernel.org/r/20221110064146.981725531@goodmis.org
+Link: https://lore.kernel.org/r/20221123201624.574672568@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clocksource/arm_arch_timer.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -687,8 +687,8 @@ static irqreturn_t arch_timer_handler_vi
+       return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
+ }
+-static __always_inline int timer_shutdown(const int access,
+-                                        struct clock_event_device *clk)
++static __always_inline int arch_timer_shutdown(const int access,
++                                             struct clock_event_device *clk)
+ {
+       unsigned long ctrl;
+@@ -701,22 +701,22 @@ static __always_inline int timer_shutdow
+ static int arch_timer_shutdown_virt(struct clock_event_device *clk)
+ {
+-      return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
++      return arch_timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
+ }
+ static int arch_timer_shutdown_phys(struct clock_event_device *clk)
+ {
+-      return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
++      return arch_timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
+ }
+ static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk)
+ {
+-      return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
++      return arch_timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
+ }
+ static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk)
+ {
+-      return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
++      return arch_timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
+ }
+ static __always_inline void set_next_event(const int access, unsigned long evt,
diff --git a/queue-6.1/clocksource-drivers-sp804-do-not-use-timer-namespace-for-timer_shutdown-function.patch b/queue-6.1/clocksource-drivers-sp804-do-not-use-timer-namespace-for-timer_shutdown-function.patch
new file mode 100644 (file)
index 0000000..2c5887f
--- /dev/null
@@ -0,0 +1,63 @@
+From aha310510@gmail.com Fri Oct 10 17:03:20 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:44 +0900
+Subject: clocksource/drivers/sp804: Do not use timer namespace for timer_shutdown() function
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-5-aha310510@gmail.com>
+
+From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
+
+[ Upstream commit 6e1fc2591f116dfb20b65cf27356475461d61bd8 ]
+
+A new "shutdown" timer state is being added to the generic timer code. One
+of the functions to change the timer into the state is called
+"timer_shutdown()". This means that there can not be other functions
+called "timer_shutdown()" as the timer code owns the "timer_*" name space.
+
+Rename timer_shutdown() to evt_timer_shutdown() to avoid this conflict.
+
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lkml.kernel.org/r/20221106212702.182883323@goodmis.org
+Link: https://lore.kernel.org/all/20221105060155.592778858@goodmis.org/
+Link: https://lore.kernel.org/r/20221110064147.158230501@goodmis.org
+Link: https://lore.kernel.org/r/20221123201624.634354813@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clocksource/timer-sp804.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/clocksource/timer-sp804.c
++++ b/drivers/clocksource/timer-sp804.c
+@@ -155,14 +155,14 @@ static irqreturn_t sp804_timer_interrupt
+       return IRQ_HANDLED;
+ }
+-static inline void timer_shutdown(struct clock_event_device *evt)
++static inline void evt_timer_shutdown(struct clock_event_device *evt)
+ {
+       writel(0, common_clkevt->ctrl);
+ }
+ static int sp804_shutdown(struct clock_event_device *evt)
+ {
+-      timer_shutdown(evt);
++      evt_timer_shutdown(evt);
+       return 0;
+ }
+@@ -171,7 +171,7 @@ static int sp804_set_periodic(struct clo
+       unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE |
+                            TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+-      timer_shutdown(evt);
++      evt_timer_shutdown(evt);
+       writel(common_clkevt->reload, common_clkevt->load);
+       writel(ctrl, common_clkevt->ctrl);
+       return 0;
diff --git a/queue-6.1/documentation-remove-bogus-claim-about-del_timer_sync.patch b/queue-6.1/documentation-remove-bogus-claim-about-del_timer_sync.patch
new file mode 100644 (file)
index 0000000..dac35f7
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-184009-greg=kroah.com@vger.kernel.org Fri Oct 10 17:03:20 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:41 +0900
+Subject: Documentation: Remove bogus claim about del_timer_sync()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-2-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit b0b0aa5d858d4d2fe39a5e4486e0550e858108f6 ]
+
+del_timer_sync() does not return the number of times it tried to delete the
+timer which rearms itself. It's clearly documented:
+
+ The function returns whether it has deactivated a pending timer or not.
+
+This part of the documentation is from 2003 where del_timer_sync() really
+returned the number of deletion attempts for unknown reasons. The code
+was rewritten in 2005, but the documentation was not updated.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.452282769@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/kernel-hacking/locking.rst                    |    3 +--
+ Documentation/translations/it_IT/kernel-hacking/locking.rst |    4 +---
+ 2 files changed, 2 insertions(+), 5 deletions(-)
+
+--- a/Documentation/kernel-hacking/locking.rst
++++ b/Documentation/kernel-hacking/locking.rst
+@@ -1006,8 +1006,7 @@ Another common problem is deleting timer
+ calling add_timer() at the end of their timer function).
+ Because this is a fairly common case which is prone to races, you should
+ 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.
++handle this case.
+ Locking Speed
+ =============
+--- a/Documentation/translations/it_IT/kernel-hacking/locking.rst
++++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst
+@@ -1027,9 +1027,7 @@ Un altro problema è l'eliminazione dei
+ da soli (chiamando add_timer() alla fine della loro esecuzione).
+ Dato che questo è un problema abbastanza comune con una propensione
+ alle corse critiche, dovreste usare del_timer_sync()
+-(``include/linux/timer.h``) per gestire questo caso. Questa ritorna il
+-numero di volte che il temporizzatore è stato interrotto prima che
+-fosse in grado di fermarlo senza che si riavviasse.
++(``include/linux/timer.h``) per gestire questo caso.
+ Velocità della sincronizzazione
+ ===============================
diff --git a/queue-6.1/documentation-replace-del_timer-del_timer_sync.patch b/queue-6.1/documentation-replace-del_timer-del_timer_sync.patch
new file mode 100644 (file)
index 0000000..fde95ea
--- /dev/null
@@ -0,0 +1,169 @@
+From aha310510@gmail.com Fri Oct 10 17:03:29 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:46 +0900
+Subject: Documentation: Replace del_timer/del_timer_sync()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-7-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 87bdd932e85881895d4720255b40ac28749c4e32 ]
+
+Adjust to the new preferred function names.
+
+Suggested-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201625.075320635@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/RCU/Design/Requirements/Requirements.rst      |    2 +-
+ Documentation/core-api/local_ops.rst                        |    2 +-
+ Documentation/kernel-hacking/locking.rst                    |   11 +++++------
+ Documentation/timers/hrtimers.rst                           |    2 +-
+ Documentation/translations/it_IT/kernel-hacking/locking.rst |   10 +++++-----
+ Documentation/translations/zh_CN/core-api/local_ops.rst     |    2 +-
+ 6 files changed, 14 insertions(+), 15 deletions(-)
+
+--- 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
+ 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_delete_sync() or similar.
+ Unfortunately, there is no way to cancel an RCU callback; once you
+ invoke call_rcu(), the callback function is eventually going to be
+--- 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
+     static void __exit test_exit(void)
+     {
+-            del_timer_sync(&test_timer);
++            timer_delete_sync(&test_timer);
+     }
+     module_init(test_init);
+--- a/Documentation/kernel-hacking/locking.rst
++++ b/Documentation/kernel-hacking/locking.rst
+@@ -967,7 +967,7 @@ you might do the following::
+             while (list) {
+                     struct foo *next = list->next;
+-                    del_timer(&list->timer);
++                    timer_delete(&list->timer);
+                     kfree(list);
+                     list = next;
+             }
+@@ -981,7 +981,7 @@ the lock after we spin_unlock_bh(), and
+ the element (which has already been freed!).
+ This can be avoided by checking the result of
+-del_timer(): if it returns 1, the timer has been deleted.
++timer_delete(): if it returns 1, the timer has been deleted.
+ If 0, it means (in this case) that it is currently running, so we can
+ do::
+@@ -990,7 +990,7 @@ do::
+                     while (list) {
+                             struct foo *next = list->next;
+-                            if (!del_timer(&list->timer)) {
++                            if (!timer_delete(&list->timer)) {
+                                     /* Give timer a chance to delete this */
+                                     spin_unlock_bh(&list_lock);
+                                     goto retry;
+@@ -1005,8 +1005,7 @@ do::
+ Another common problem is deleting timers which restart themselves (by
+ calling add_timer() at the end of their timer function).
+ Because this is a fairly common case which is prone to races, you should
+-use del_timer_sync() (``include/linux/timer.h``) to
+-handle this case.
++use timer_delete_sync() (``include/linux/timer.h``) to
+ Locking Speed
+ =============
+@@ -1334,7 +1333,7 @@ lock.
+ -  kfree()
+--  add_timer() and del_timer()
++-  add_timer() and timer_delete()
+ Mutex API reference
+ ===================
+--- a/Documentation/timers/hrtimers.rst
++++ b/Documentation/timers/hrtimers.rst
+@@ -118,7 +118,7 @@ existing timer wheel code, as it is matu
+ was not really a win, due to the different data structures. Also, the
+ hrtimer functions now have clearer behavior and clearer names - such as
+ hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly
+-equivalent to del_timer() and del_timer_sync()] - so there's no direct
++equivalent to timer_delete() and timer_delete_sync()] - so there's no direct
+ 1:1 mapping between them on the algorithmic level, and thus no real
+ potential for code sharing either.
+--- a/Documentation/translations/it_IT/kernel-hacking/locking.rst
++++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst
+@@ -990,7 +990,7 @@ potreste fare come segue::
+             while (list) {
+                     struct foo *next = list->next;
+-                    del_timer(&list->timer);
++                    timer_delete(&list->timer);
+                     kfree(list);
+                     list = next;
+             }
+@@ -1003,7 +1003,7 @@ e prenderà il *lock* solo dopo spin_unl
+ di eliminare il suo oggetto (che però è già stato eliminato).
+ Questo può essere evitato controllando il valore di ritorno di
+-del_timer(): se ritorna 1, il temporizzatore è stato già
++timer_delete(): se ritorna 1, il temporizzatore è stato già
+ rimosso. Se 0, significa (in questo caso) che il temporizzatore è in
+ esecuzione, quindi possiamo fare come segue::
+@@ -1012,7 +1012,7 @@ esecuzione, quindi possiamo fare come se
+                     while (list) {
+                             struct foo *next = list->next;
+-                            if (!del_timer(&list->timer)) {
++                            if (!timer_delete(&list->timer)) {
+                                     /* Give timer a chance to delete this */
+                                     spin_unlock_bh(&list_lock);
+                                     goto retry;
+@@ -1026,7 +1026,7 @@ esecuzione, quindi possiamo fare come se
+ Un altro problema è l'eliminazione dei temporizzatori che si riavviano
+ da soli (chiamando add_timer() alla fine della loro esecuzione).
+ Dato che questo è un problema abbastanza comune con una propensione
+-alle corse critiche, dovreste usare del_timer_sync()
++alle corse critiche, dovreste usare timer_delete_sync()
+ (``include/linux/timer.h``) per gestire questo caso.
+ Velocità della sincronizzazione
+@@ -1372,7 +1372,7 @@ contesto, o trattenendo un qualsiasi *lo
+ -  kfree()
+--  add_timer() e del_timer()
++-  add_timer() e timer_delete()
+ Riferimento per l'API dei Mutex
+ ===============================
+--- a/Documentation/translations/zh_CN/core-api/local_ops.rst
++++ b/Documentation/translations/zh_CN/core-api/local_ops.rst
+@@ -185,7 +185,7 @@ UPä¹\8bé\97´æ²¡æ\9c\89ä¸\8då\90\8cç\9a\84è¡\8c为ï¼\8cå\9c¨ä½ ç\9a
+     static void __exit test_exit(void)
+     {
+-            del_timer_sync(&test_timer);
++            timer_delete_sync(&test_timer);
+     }
+     module_init(test_init);
index c883389f6f8063eba791048cb3946c32af4bc44a..98394930612904f2f8d82d926681ecb318b00901 100644 (file)
@@ -21,3 +21,15 @@ usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch
 usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch
 usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch
 usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch
+documentation-remove-bogus-claim-about-del_timer_sync.patch
+arm-spear-do-not-use-timer-namespace-for-timer_shutdown-function.patch
+clocksource-drivers-arm_arch_timer-do-not-use-timer-namespace-for-timer_shutdown-function.patch
+clocksource-drivers-sp804-do-not-use-timer-namespace-for-timer_shutdown-function.patch
+timers-replace-bug_on-s.patch
+documentation-replace-del_timer-del_timer_sync.patch
+timers-silently-ignore-timers-with-a-null-function.patch
+timers-split-del_timer-to-prepare-for-shutdown-mode.patch
+timers-add-shutdown-mechanism-to-the-internal-functions.patch
+timers-provide-timer_shutdown.patch
+timers-update-the-documentation-to-reflect-on-the-new-timer_shutdown-api.patch
+bluetooth-hci_qca-fix-the-teardown-problem-for-real.patch
diff --git a/queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functions.patch b/queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functions.patch
new file mode 100644 (file)
index 0000000..945e189
--- /dev/null
@@ -0,0 +1,184 @@
+From aha310510@gmail.com Fri Oct 10 17:03:44 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:49 +0900
+Subject: timers: Add shutdown mechanism to the internal functions
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-10-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 0cc04e80458a822300b93f82ed861a513edde194 ]
+
+Tearing down timers which have circular dependencies to other
+functionality, e.g. workqueues, where the timer can schedule work and work
+can arm timers, is not trivial.
+
+In those cases it is desired to shutdown the timer in a way which prevents
+rearming of the timer. The mechanism to do so is to set timer->function to
+NULL and use this as an indicator for the timer arming functions to ignore
+the (re)arm request.
+
+Add a shutdown argument to the relevant internal functions which makes the
+actual deactivation code set timer->function to NULL which in turn prevents
+rearming of the timer.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/20221123201625.253883224@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/timer.c |   62 +++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 54 insertions(+), 8 deletions(-)
+
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1300,12 +1300,19 @@ EXPORT_SYMBOL_GPL(add_timer_on);
+ /**
+  * __timer_delete - Internal function: Deactivate a timer
+  * @timer:    The timer to be deactivated
++ * @shutdown: If true, this indicates that the timer is about to be
++ *            shutdown permanently.
++ *
++ * If @shutdown is true then @timer->function is set to NULL under the
++ * timer base lock which prevents further rearming of the time. In that
++ * case any attempt to rearm @timer after this function returns will be
++ * silently ignored.
+  *
+  * Return:
+  * * %0 - The timer was not pending
+  * * %1 - The timer was pending and deactivated
+  */
+-static int __timer_delete(struct timer_list *timer)
++static int __timer_delete(struct timer_list *timer, bool shutdown)
+ {
+       struct timer_base *base;
+       unsigned long flags;
+@@ -1313,9 +1320,22 @@ static int __timer_delete(struct timer_l
+       debug_assert_init(timer);
+-      if (timer_pending(timer)) {
++      /*
++       * If @shutdown is set then the lock has to be taken whether the
++       * timer is pending or not to protect against a concurrent rearm
++       * which might hit between the lockless pending check and the lock
++       * aquisition. By taking the lock it is ensured that such a newly
++       * enqueued timer is dequeued and cannot end up with
++       * timer->function == NULL in the expiry code.
++       *
++       * If timer->function is currently executed, then this makes sure
++       * that the callback cannot requeue the timer.
++       */
++      if (timer_pending(timer) || shutdown) {
+               base = lock_timer_base(timer, &flags);
+               ret = detach_if_pending(timer, base, true);
++              if (shutdown)
++                      timer->function = NULL;
+               raw_spin_unlock_irqrestore(&base->lock, flags);
+       }
+@@ -1338,20 +1358,31 @@ static int __timer_delete(struct timer_l
+  */
+ int timer_delete(struct timer_list *timer)
+ {
+-      return __timer_delete(timer);
++      return __timer_delete(timer, false);
+ }
+ EXPORT_SYMBOL(timer_delete);
+ /**
+  * __try_to_del_timer_sync - Internal function: Try to deactivate a timer
+  * @timer:    Timer to deactivate
++ * @shutdown: If true, this indicates that the timer is about to be
++ *            shutdown permanently.
++ *
++ * If @shutdown is true then @timer->function is set to NULL under the
++ * timer base lock which prevents further rearming of the timer. Any
++ * attempt to rearm @timer after this function returns will be silently
++ * ignored.
++ *
++ * This function cannot guarantee that the timer cannot be rearmed
++ * right after dropping the base lock if @shutdown is false. That
++ * needs to be prevented by the calling code if necessary.
+  *
+  * Return:
+  * * %0  - The timer was not pending
+  * * %1  - The timer was pending and deactivated
+  * * %-1 - The timer callback function is running on a different CPU
+  */
+-static int __try_to_del_timer_sync(struct timer_list *timer)
++static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown)
+ {
+       struct timer_base *base;
+       unsigned long flags;
+@@ -1363,6 +1394,8 @@ static int __try_to_del_timer_sync(struc
+       if (base->running_timer != timer)
+               ret = detach_if_pending(timer, base, true);
++      if (shutdown)
++              timer->function = NULL;
+       raw_spin_unlock_irqrestore(&base->lock, flags);
+@@ -1387,7 +1420,7 @@ static int __try_to_del_timer_sync(struc
+  */
+ int try_to_del_timer_sync(struct timer_list *timer)
+ {
+-      return __try_to_del_timer_sync(timer);
++      return __try_to_del_timer_sync(timer, false);
+ }
+ EXPORT_SYMBOL(try_to_del_timer_sync);
+@@ -1468,12 +1501,25 @@ static inline void del_timer_wait_runnin
+  * __timer_delete_sync - Internal function: Deactivate a timer and wait
+  *                     for the handler to finish.
+  * @timer:    The timer to be deactivated
++ * @shutdown: If true, @timer->function will be set to NULL under the
++ *            timer base lock which prevents rearming of @timer
++ *
++ * If @shutdown is not set the timer can be rearmed later. If the timer can
++ * be rearmed concurrently, i.e. after dropping the base lock then the
++ * return value is meaningless.
++ *
++ * If @shutdown is set then @timer->function is set to NULL under timer
++ * base lock which prevents rearming of the timer. Any attempt to rearm
++ * a shutdown timer is silently ignored.
++ *
++ * If the timer should be reused after shutdown it has to be initialized
++ * again.
+  *
+  * Return:
+  * * %0       - The timer was not pending
+  * * %1       - The timer was pending and deactivated
+  */
+-static int __timer_delete_sync(struct timer_list *timer)
++static int __timer_delete_sync(struct timer_list *timer, bool shutdown)
+ {
+       int ret;
+@@ -1503,7 +1549,7 @@ static int __timer_delete_sync(struct ti
+               lockdep_assert_preemption_enabled();
+       do {
+-              ret = __try_to_del_timer_sync(timer);
++              ret = __try_to_del_timer_sync(timer, shutdown);
+               if (unlikely(ret < 0)) {
+                       del_timer_wait_running(timer);
+@@ -1555,7 +1601,7 @@ static int __timer_delete_sync(struct ti
+  */
+ int timer_delete_sync(struct timer_list *timer)
+ {
+-      return __timer_delete_sync(timer);
++      return __timer_delete_sync(timer, false);
+ }
+ EXPORT_SYMBOL(timer_delete_sync);
diff --git a/queue-6.1/timers-provide-timer_shutdown.patch b/queue-6.1/timers-provide-timer_shutdown.patch
new file mode 100644 (file)
index 0000000..b095a2d
--- /dev/null
@@ -0,0 +1,148 @@
+From aha310510@gmail.com Fri Oct 10 17:03:52 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:50 +0900
+Subject: timers: Provide timer_shutdown[_sync]()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-11-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit f571faf6e443b6011ccb585d57866177af1f643c ]
+
+Tearing down timers which have circular dependencies to other
+functionality, e.g. workqueues, where the timer can schedule work and work
+can arm timers, is not trivial.
+
+In those cases it is desired to shutdown the timer in a way which prevents
+rearming of the timer. The mechanism to do so is to set timer->function to
+NULL and use this as an indicator for the timer arming functions to ignore
+the (re)arm request.
+
+Expose new interfaces for this: timer_shutdown_sync() and timer_shutdown().
+
+timer_shutdown_sync() has the same functionality as timer_delete_sync()
+plus the NULL-ification of the timer function.
+
+timer_shutdown() has the same functionality as timer_delete() plus the
+NULL-ification of the timer function.
+
+In both cases the rearming of the timer is prevented by silently discarding
+rearm attempts due to timer->function being NULL.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/20221123201625.314230270@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/timer.h |    2 +
+ kernel/time/timer.c   |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 68 insertions(+)
+
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -184,6 +184,8 @@ extern void add_timer(struct timer_list
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+ extern int timer_delete_sync(struct timer_list *timer);
+ extern int timer_delete(struct timer_list *timer);
++extern int timer_shutdown_sync(struct timer_list *timer);
++extern int timer_shutdown(struct timer_list *timer);
+ /**
+  * del_timer_sync - Delete a pending timer and wait for a running callback
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1363,6 +1363,27 @@ int timer_delete(struct timer_list *time
+ EXPORT_SYMBOL(timer_delete);
+ /**
++ * timer_shutdown - Deactivate a timer and prevent rearming
++ * @timer:    The timer to be deactivated
++ *
++ * The function does not wait for an eventually running timer callback on a
++ * different CPU but it prevents rearming of the timer. Any attempt to arm
++ * @timer after this function returns will be silently ignored.
++ *
++ * This function is useful for teardown code and should only be used when
++ * timer_shutdown_sync() cannot be invoked due to locking or context constraints.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending
++ */
++int timer_shutdown(struct timer_list *timer)
++{
++      return __timer_delete(timer, true);
++}
++EXPORT_SYMBOL_GPL(timer_shutdown);
++
++/**
+  * __try_to_del_timer_sync - Internal function: Try to deactivate a timer
+  * @timer:    Timer to deactivate
+  * @shutdown: If true, this indicates that the timer is about to be
+@@ -1595,6 +1616,9 @@ static int __timer_delete_sync(struct ti
+  * lock. If there is the possibility of a concurrent rearm then the return
+  * value of the function is meaningless.
+  *
++ * If such a guarantee is needed, e.g. for teardown situations then use
++ * timer_shutdown_sync() instead.
++ *
+  * Return:
+  * * %0       - The timer was not pending
+  * * %1       - The timer was pending and deactivated
+@@ -1605,6 +1629,48 @@ int timer_delete_sync(struct timer_list
+ }
+ EXPORT_SYMBOL(timer_delete_sync);
++/**
++ * timer_shutdown_sync - Shutdown a timer and prevent rearming
++ * @timer: The timer to be shutdown
++ *
++ * When the function returns it is guaranteed that:
++ *   - @timer is not queued
++ *   - The callback function of @timer is not running
++ *   - @timer cannot be enqueued again. Any attempt to rearm
++ *     @timer is silently ignored.
++ *
++ * See timer_delete_sync() for synchronization rules.
++ *
++ * This function is useful for final teardown of an infrastructure where
++ * the timer is subject to a circular dependency problem.
++ *
++ * A common pattern for this is a timer and a workqueue where the timer can
++ * schedule work and work can arm the timer. On shutdown the workqueue must
++ * be destroyed and the timer must be prevented from rearming. Unless the
++ * code has conditionals like 'if (mything->in_shutdown)' to prevent that
++ * there is no way to get this correct with timer_delete_sync().
++ *
++ * timer_shutdown_sync() is solving the problem. The correct ordering of
++ * calls in this case is:
++ *
++ *    timer_shutdown_sync(&mything->timer);
++ *    workqueue_destroy(&mything->workqueue);
++ *
++ * After this 'mything' can be safely freed.
++ *
++ * This obviously implies that the timer is not required to be functional
++ * for the rest of the shutdown operation.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending
++ */
++int timer_shutdown_sync(struct timer_list *timer)
++{
++      return __timer_delete_sync(timer, true);
++}
++EXPORT_SYMBOL_GPL(timer_shutdown_sync);
++
+ static void call_timer_fn(struct timer_list *timer,
+                         void (*fn)(struct timer_list *),
+                         unsigned long baseclk)
diff --git a/queue-6.1/timers-replace-bug_on-s.patch b/queue-6.1/timers-replace-bug_on-s.patch
new file mode 100644 (file)
index 0000000..76b71ae
--- /dev/null
@@ -0,0 +1,75 @@
+From aha310510@gmail.com Fri Oct 10 17:03:24 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:45 +0900
+Subject: timers: Replace BUG_ON()s
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-6-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 82ed6f7ef58f9634fe4462dd721902c580f01569 ]
+
+The timer code still has a few BUG_ON()s left which are crashing the kernel
+in situations where it still can recover or simply refuse to take an
+action.
+
+Remove the one in the hotplug callback which checks for the CPU being
+offline. If that happens then the whole hotplug machinery will explode in
+colourful ways.
+
+Replace the rest with WARN_ON_ONCE() and conditional returns where
+appropriate.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.769128888@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/timer.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1208,7 +1208,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);
+@@ -1227,7 +1228,8 @@ void add_timer_on(struct timer_list *tim
+       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);
+@@ -2047,8 +2049,6 @@ int timers_dead_cpu(unsigned int cpu)
+       struct timer_base *new_base;
+       int b, i;
+-      BUG_ON(cpu_online(cpu));
+-
+       for (b = 0; b < NR_BASES; b++) {
+               old_base = per_cpu_ptr(&timer_bases[b], cpu);
+               new_base = get_cpu_ptr(&timer_bases[b]);
+@@ -2065,7 +2065,8 @@ int timers_dead_cpu(unsigned int cpu)
+                */
+               forward_timer_base(new_base);
+-              BUG_ON(old_base->running_timer);
++              WARN_ON_ONCE(old_base->running_timer);
++              old_base->running_timer = NULL;
+               for (i = 0; i < WHEEL_SIZE; i++)
+                       migrate_timer_list(new_base, old_base->vectors + i);
diff --git a/queue-6.1/timers-silently-ignore-timers-with-a-null-function.patch b/queue-6.1/timers-silently-ignore-timers-with-a-null-function.patch
new file mode 100644 (file)
index 0000000..7eca926
--- /dev/null
@@ -0,0 +1,188 @@
+From aha310510@gmail.com Fri Oct 10 17:03:34 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:47 +0900
+Subject: timers: Silently ignore timers with a NULL function
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-8-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit d02e382cef06cc73561dd32dfdc171c00dcc416d ]
+
+Tearing down timers which have circular dependencies to other
+functionality, e.g. workqueues, where the timer can schedule work and work
+can arm timers, is not trivial.
+
+In those cases it is desired to shutdown the timer in a way which prevents
+rearming of the timer. The mechanism to do so is to set timer->function to
+NULL and use this as an indicator for the timer arming functions to ignore
+the (re)arm request.
+
+In preparation for that replace the warnings in the relevant code paths
+with checks for timer->function == NULL. If the pointer is NULL, then
+discard the rearm request silently.
+
+Add debug_assert_init() instead of the WARN_ON_ONCE(!timer->function)
+checks so that debug objects can warn about non-initialized timers.
+
+The warning of debug objects does not warn if timer->function == NULL.  It
+warns when timer was not initialized using timer_setup[_on_stack]() or via
+DEFINE_TIMER(). If developers fail to enable debug objects and then waste
+lots of time to figure out why their non-initialized timer is not firing,
+they deserve it. Same for initializing a timer with a NULL function.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/87wn7kdann.ffs@tglx
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/timer.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 52 insertions(+), 5 deletions(-)
+
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1017,7 +1017,7 @@ __mod_timer(struct timer_list *timer, un
+       unsigned int idx = UINT_MAX;
+       int ret = 0;
+-      BUG_ON(!timer->function);
++      debug_assert_init(timer);
+       /*
+        * This is a common optimization triggered by the networking code - if
+@@ -1044,6 +1044,14 @@ __mod_timer(struct timer_list *timer, un
+                * dequeue/enqueue dance.
+                */
+               base = lock_timer_base(timer, &flags);
++              /*
++               * Has @timer been shutdown? This needs to be evaluated
++               * while holding base lock to prevent a race against the
++               * shutdown code.
++               */
++              if (!timer->function)
++                      goto out_unlock;
++
+               forward_timer_base(base);
+               if (timer_pending(timer) && (options & MOD_TIMER_REDUCE) &&
+@@ -1070,6 +1078,14 @@ __mod_timer(struct timer_list *timer, un
+               }
+       } else {
+               base = lock_timer_base(timer, &flags);
++              /*
++               * Has @timer been shutdown? This needs to be evaluated
++               * while holding base lock to prevent a race against the
++               * shutdown code.
++               */
++              if (!timer->function)
++                      goto out_unlock;
++
+               forward_timer_base(base);
+       }
+@@ -1128,8 +1144,12 @@ out_unlock:
+  * mod_timer_pending() is the same for pending timers as mod_timer(), but
+  * will not activate inactive timers.
+  *
++ * If @timer->function == NULL then the start operation is silently
++ * discarded.
++ *
+  * Return:
+- * * %0 - The timer was inactive and not modified
++ * * %0 - The timer was inactive and not modified or was in
++ *      shutdown state and the operation was discarded
+  * * %1 - The timer was active and requeued to expire at @expires
+  */
+ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
+@@ -1155,8 +1175,12 @@ EXPORT_SYMBOL(mod_timer_pending);
+  * same timer, then mod_timer() is the only safe way to modify the timeout,
+  * since add_timer() cannot modify an already running timer.
+  *
++ * If @timer->function == NULL then the start operation is silently
++ * discarded. In this case the return value is 0 and meaningless.
++ *
+  * Return:
+- * * %0 - The timer was inactive and started
++ * * %0 - The timer was inactive and started or was in shutdown
++ *      state and the operation was discarded
+  * * %1 - The timer was active and requeued to expire at @expires or
+  *      the timer was active and not modified because @expires did
+  *      not change the effective expiry time
+@@ -1176,8 +1200,12 @@ EXPORT_SYMBOL(mod_timer);
+  * modify an enqueued timer if that would reduce the expiration time. If
+  * @timer is not enqueued it starts the timer.
+  *
++ * If @timer->function == NULL then the start operation is silently
++ * discarded.
++ *
+  * Return:
+- * * %0 - The timer was inactive and started
++ * * %0 - The timer was inactive and started or was in shutdown
++ *      state and the operation was discarded
+  * * %1 - The timer was active and requeued to expire at @expires or
+  *      the timer was active and not modified because @expires
+  *      did not change the effective expiry time such that the
+@@ -1200,6 +1228,9 @@ EXPORT_SYMBOL(timer_reduce);
+  * The @timer->expires and @timer->function fields must be set prior
+  * to calling this function.
+  *
++ * If @timer->function == NULL then the start operation is silently
++ * discarded.
++ *
+  * If @timer->expires is already in the past @timer will be queued to
+  * expire at the next timer tick.
+  *
+@@ -1228,7 +1259,9 @@ void add_timer_on(struct timer_list *tim
+       struct timer_base *new_base, *base;
+       unsigned long flags;
+-      if (WARN_ON_ONCE(timer_pending(timer) || !timer->function))
++      debug_assert_init(timer);
++
++      if (WARN_ON_ONCE(timer_pending(timer)))
+               return;
+       new_base = get_timer_cpu_base(timer->flags, cpu);
+@@ -1239,6 +1272,13 @@ void add_timer_on(struct timer_list *tim
+        * wrong base locked.  See lock_timer_base().
+        */
+       base = lock_timer_base(timer, &flags);
++      /*
++       * Has @timer been shutdown? This needs to be evaluated while
++       * holding base lock to prevent a race against the shutdown code.
++       */
++      if (!timer->function)
++              goto out_unlock;
++
+       if (base != new_base) {
+               timer->flags |= TIMER_MIGRATING;
+@@ -1252,6 +1292,7 @@ void add_timer_on(struct timer_list *tim
+       debug_timer_activate(timer);
+       internal_add_timer(base, timer);
++out_unlock:
+       raw_spin_unlock_irqrestore(&base->lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(add_timer_on);
+@@ -1541,6 +1582,12 @@ static void expire_timers(struct timer_b
+               fn = timer->function;
++              if (WARN_ON_ONCE(!fn)) {
++                      /* Should never happen. Emphasis on should! */
++                      base->running_timer = NULL;
++                      continue;
++              }
++
+               if (timer->flags & TIMER_IRQSAFE) {
+                       raw_spin_unlock(&base->lock);
+                       call_timer_fn(timer, fn, baseclk);
diff --git a/queue-6.1/timers-split-del_timer-to-prepare-for-shutdown-mode.patch b/queue-6.1/timers-split-del_timer-to-prepare-for-shutdown-mode.patch
new file mode 100644 (file)
index 0000000..59734a1
--- /dev/null
@@ -0,0 +1,251 @@
+From aha310510@gmail.com Fri Oct 10 17:03:39 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:48 +0900
+Subject: timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown mode
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-9-aha310510@gmail.com>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 8553b5f2774a66b1f293b7d783934210afb8f23c ]
+
+Tearing down timers which have circular dependencies to other
+functionality, e.g. workqueues, where the timer can schedule work and work
+can arm timers, is not trivial.
+
+In those cases it is desired to shutdown the timer in a way which prevents
+rearming of the timer. The mechanism to do so is to set timer->function to
+NULL and use this as an indicator for the timer arming functions to ignore
+the (re)arm request.
+
+Split the inner workings of try_do_del_timer_sync(), del_timer_sync() and
+del_timer() into helper functions to prepare for implementing the shutdown
+functionality.
+
+No functional change.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/20221123201625.195147423@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/timer.c |  143 +++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 92 insertions(+), 51 deletions(-)
+
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1298,20 +1298,14 @@ out_unlock:
+ EXPORT_SYMBOL_GPL(add_timer_on);
+ /**
+- * timer_delete - Deactivate a timer
++ * __timer_delete - Internal function: Deactivate a timer
+  * @timer:    The timer to be deactivated
+  *
+- * The function only deactivates a pending timer, but contrary to
+- * timer_delete_sync() it does not take into account whether the timer's
+- * callback function is concurrently executed on a different CPU or not.
+- * It neither prevents rearming of the timer. If @timer can be rearmed
+- * concurrently then the return value of this function is meaningless.
+- *
+  * Return:
+  * * %0 - The timer was not pending
+  * * %1 - The timer was pending and deactivated
+  */
+-int timer_delete(struct timer_list *timer)
++static int __timer_delete(struct timer_list *timer)
+ {
+       struct timer_base *base;
+       unsigned long flags;
+@@ -1327,25 +1321,37 @@ int timer_delete(struct timer_list *time
+       return ret;
+ }
+-EXPORT_SYMBOL(timer_delete);
+ /**
+- * try_to_del_timer_sync - Try to deactivate a timer
+- * @timer:    Timer to deactivate
++ * timer_delete - Deactivate a timer
++ * @timer:    The timer to be deactivated
+  *
+- * This function tries to deactivate a timer. On success the timer is not
+- * queued and the timer callback function is not running on any CPU.
++ * The function only deactivates a pending timer, but contrary to
++ * timer_delete_sync() it does not take into account whether the timer's
++ * callback function is concurrently executed on a different CPU or not.
++ * It neither prevents rearming of the timer.  If @timer can be rearmed
++ * concurrently then the return value of this function is meaningless.
+  *
+- * This function does not guarantee that the timer cannot be rearmed right
+- * after dropping the base lock. That needs to be prevented by the calling
+- * code if necessary.
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
++ */
++int timer_delete(struct timer_list *timer)
++{
++      return __timer_delete(timer);
++}
++EXPORT_SYMBOL(timer_delete);
++
++/**
++ * __try_to_del_timer_sync - Internal function: Try to deactivate a timer
++ * @timer:    Timer to deactivate
+  *
+  * Return:
+  * * %0  - The timer was not pending
+  * * %1  - The timer was pending and deactivated
+  * * %-1 - The timer callback function is running on a different CPU
+  */
+-int try_to_del_timer_sync(struct timer_list *timer)
++static int __try_to_del_timer_sync(struct timer_list *timer)
+ {
+       struct timer_base *base;
+       unsigned long flags;
+@@ -1362,6 +1368,27 @@ int try_to_del_timer_sync(struct timer_l
+       return ret;
+ }
++
++/**
++ * try_to_del_timer_sync - Try to deactivate a timer
++ * @timer:    Timer to deactivate
++ *
++ * This function tries to deactivate a timer. On success the timer is not
++ * queued and the timer callback function is not running on any CPU.
++ *
++ * This function does not guarantee that the timer cannot be rearmed right
++ * after dropping the base lock. That needs to be prevented by the calling
++ * code if necessary.
++ *
++ * Return:
++ * * %0  - The timer was not pending
++ * * %1  - The timer was pending and deactivated
++ * * %-1 - The timer callback function is running on a different CPU
++ */
++int try_to_del_timer_sync(struct timer_list *timer)
++{
++      return __try_to_del_timer_sync(timer);
++}
+ EXPORT_SYMBOL(try_to_del_timer_sync);
+ #ifdef CONFIG_PREEMPT_RT
+@@ -1438,45 +1465,15 @@ static inline void del_timer_wait_runnin
+ #endif
+ /**
+- * timer_delete_sync - Deactivate a timer and wait for the handler to finish.
++ * __timer_delete_sync - Internal function: Deactivate a timer and wait
++ *                     for the handler to finish.
+  * @timer:    The timer to be deactivated
+  *
+- * Synchronization rules: Callers must prevent restarting of the timer,
+- * otherwise this function is meaningless. It must not be called from
+- * interrupt contexts unless the timer is an irqsafe one. The caller must
+- * not hold locks which would prevent completion of the timer's callback
+- * function. The timer's handler must not call add_timer_on(). Upon exit
+- * the timer is not queued and the handler is not running on any CPU.
+- *
+- * For !irqsafe timers, the caller must not hold locks that are held in
+- * interrupt context. Even if the lock has nothing to do with the timer in
+- * question.  Here's why::
+- *
+- *    CPU0                             CPU1
+- *    ----                             ----
+- *                                     <SOFTIRQ>
+- *                                       call_timer_fn();
+- *                                       base->running_timer = mytimer;
+- *    spin_lock_irq(somelock);
+- *                                     <IRQ>
+- *                                        spin_lock(somelock);
+- *    timer_delete_sync(mytimer);
+- *    while (base->running_timer == mytimer);
+- *
+- * Now timer_delete_sync() will never return and never release somelock.
+- * The interrupt on the other CPU is waiting to grab somelock but it has
+- * interrupted the softirq that CPU0 is waiting to finish.
+- *
+- * This function cannot guarantee that the timer is not rearmed again by
+- * some concurrent or preempting code, right after it dropped the base
+- * lock. If there is the possibility of a concurrent rearm then the return
+- * value of the function is meaningless.
+- *
+  * Return:
+  * * %0       - The timer was not pending
+  * * %1       - The timer was pending and deactivated
+  */
+-int timer_delete_sync(struct timer_list *timer)
++static int __timer_delete_sync(struct timer_list *timer)
+ {
+       int ret;
+@@ -1506,7 +1503,7 @@ int timer_delete_sync(struct timer_list
+               lockdep_assert_preemption_enabled();
+       do {
+-              ret = try_to_del_timer_sync(timer);
++              ret = __try_to_del_timer_sync(timer);
+               if (unlikely(ret < 0)) {
+                       del_timer_wait_running(timer);
+@@ -1516,6 +1513,50 @@ int timer_delete_sync(struct timer_list
+       return ret;
+ }
++
++/**
++ * timer_delete_sync - Deactivate a timer and wait for the handler to finish.
++ * @timer:    The timer to be deactivated
++ *
++ * Synchronization rules: Callers must prevent restarting of the timer,
++ * otherwise this function is meaningless. It must not be called from
++ * interrupt contexts unless the timer is an irqsafe one. The caller must
++ * not hold locks which would prevent completion of the timer's callback
++ * function. The timer's handler must not call add_timer_on(). Upon exit
++ * the timer is not queued and the handler is not running on any CPU.
++ *
++ * For !irqsafe timers, the caller must not hold locks that are held in
++ * interrupt context. Even if the lock has nothing to do with the timer in
++ * question.  Here's why::
++ *
++ *    CPU0                             CPU1
++ *    ----                             ----
++ *                                     <SOFTIRQ>
++ *                                       call_timer_fn();
++ *                                       base->running_timer = mytimer;
++ *    spin_lock_irq(somelock);
++ *                                     <IRQ>
++ *                                        spin_lock(somelock);
++ *    timer_delete_sync(mytimer);
++ *    while (base->running_timer == mytimer);
++ *
++ * Now timer_delete_sync() will never return and never release somelock.
++ * The interrupt on the other CPU is waiting to grab somelock but it has
++ * interrupted the softirq that CPU0 is waiting to finish.
++ *
++ * This function cannot guarantee that the timer is not rearmed again by
++ * some concurrent or preempting code, right after it dropped the base
++ * lock. If there is the possibility of a concurrent rearm then the return
++ * value of the function is meaningless.
++ *
++ * Return:
++ * * %0       - The timer was not pending
++ * * %1       - The timer was pending and deactivated
++ */
++int timer_delete_sync(struct timer_list *timer)
++{
++      return __timer_delete_sync(timer);
++}
+ EXPORT_SYMBOL(timer_delete_sync);
+ static void call_timer_fn(struct timer_list *timer,
diff --git a/queue-6.1/timers-update-the-documentation-to-reflect-on-the-new-timer_shutdown-api.patch b/queue-6.1/timers-update-the-documentation-to-reflect-on-the-new-timer_shutdown-api.patch
new file mode 100644 (file)
index 0000000..5b9dd9e
--- /dev/null
@@ -0,0 +1,84 @@
+From aha310510@gmail.com Fri Oct 10 17:03:53 2025
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Sat, 11 Oct 2025 00:02:51 +0900
+Subject: timers: Update the documentation to reflect on the new timer_shutdown() API
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, tglx@linutronix.de, Julia.Lawall@inria.fr, akpm@linux-foundation.org, anna-maria@linutronix.de, arnd@arndb.de, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux@roeck-us.net, luiz.dentz@gmail.com, marcel@holtmann.org, maz@kernel.org, peterz@infradead.org, rostedt@goodmis.org, sboyd@kernel.org, viresh.kumar@linaro.org, Jacob Keller <jacob.e.keller@intel.com>, Jeongjun Park <aha310510@gmail.com>
+Message-ID: <20251010150252.1115788-12-aha310510@gmail.com>
+
+From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
+
+[ Upstream commit a31323bef2b66455920d054b160c17d4240f8fd4 ]
+
+In order to make sure that a timer is not re-armed after it is stopped
+before freeing, a new shutdown state is added to the timer code. The API
+timer_shutdown_sync() and timer_shutdown() must be called before the
+object that holds the timer can be freed.
+
+Update the documentation to reflect this new workflow.
+
+[ tglx: Updated to the new semantics and updated the zh_CN version ]
+
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221110064147.712934793@goodmis.org
+Link: https://lore.kernel.org/r/20221123201625.375284489@linutronix.de
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/RCU/Design/Requirements/Requirements.rst  |    2 +-
+ Documentation/core-api/local_ops.rst                    |    2 +-
+ Documentation/kernel-hacking/locking.rst                |    5 +++++
+ Documentation/translations/zh_CN/core-api/local_ops.rst |    2 +-
+ 4 files changed, 8 insertions(+), 3 deletions(-)
+
+--- 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
+ 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 timer_delete_sync() or similar.
++with via timer_shutdown_sync() or similar.
+ Unfortunately, there is no way to cancel an RCU callback; once you
+ invoke call_rcu(), the callback function is eventually going to be
+--- 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
+     static void __exit test_exit(void)
+     {
+-            timer_delete_sync(&test_timer);
++            timer_shutdown_sync(&test_timer);
+     }
+     module_init(test_init);
+--- a/Documentation/kernel-hacking/locking.rst
++++ b/Documentation/kernel-hacking/locking.rst
+@@ -1007,6 +1007,11 @@ calling add_timer() at the end of their
+ Because this is a fairly common case which is prone to races, you should
+ use timer_delete_sync() (``include/linux/timer.h``) to
++Before freeing a timer, timer_shutdown() or timer_shutdown_sync() should be
++called which will keep it from being rearmed. Any subsequent attempt to
++rearm the timer will be silently ignored by the core code.
++
++
+ Locking Speed
+ =============
+--- a/Documentation/translations/zh_CN/core-api/local_ops.rst
++++ b/Documentation/translations/zh_CN/core-api/local_ops.rst
+@@ -185,7 +185,7 @@ UPä¹\8bé\97´æ²¡æ\9c\89ä¸\8då\90\8cç\9a\84è¡\8c为ï¼\8cå\9c¨ä½ ç\9a
+     static void __exit test_exit(void)
+     {
+-            timer_delete_sync(&test_timer);
++            timer_shutdown_sync(&test_timer);
+     }
+     module_init(test_init);