From patchwork Wed Nov 23 20:18:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF151C4332F for ; Wed, 23 Nov 2022 20:19:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239222AbiKWUTs (ORCPT ); Wed, 23 Nov 2022 15:19:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239259AbiKWUSz (ORCPT ); Wed, 23 Nov 2022 15:18:55 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A82C991C3D; Wed, 23 Nov 2022 12:18:33 -0800 (PST) Message-ID: <20221123201624.452282769@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234711; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=A2SY6j6h29m5XzjJBWQT9Lgn9maXUZXQdJe6ibdVF0Q=; b=oxrZpu8gy33vwLcTyeM9oUZzX6+fHMndkO85dqJdBjQrSOlDMZXxKsuysYXvvmQHsqdC1S dKmZpYRS9o//g+Tdxxsl3tdMHRDB2YGKAGnEx49qjFcr0Gi411RoXRYTsOxxswVKJax0CZ vduRr0EltYhwJQk6uWt+OB4vzGGMuKuDZIrGn1PmUj9YEv4vNktARpIEfHcJqkmECgFcBm +ehVfa4j/C9yB4fL3cStETcyNfdvCYhhQyw6Ac8e1BUk3vWTcJmynotgVrc6CglkAm/XeB j1CBJiGkmlaI1IxWLnv2jiCv/HSwdnC5Qfh4rV6zCBmvJv7FKJsyFk+GFnePqA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234711; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=A2SY6j6h29m5XzjJBWQT9Lgn9maXUZXQdJe6ibdVF0Q=; b=frCxv+JYFv1m5JDYMLoiXzjV44LB/mMTKPW9MZAUzVGCvutW27XlDRZ8jQv7X5I18KDaiL g2pBWVq5VkpFKbBg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 01/17] Documentation: Remove bogus claim about del_timer_sync() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:31 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Reviewed-by: Jacob Keller --- 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 =============================== From patchwork Wed Nov 23 20:18:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054206 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE2F8C43219 for ; Wed, 23 Nov 2022 20:19:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236790AbiKWUTv (ORCPT ); Wed, 23 Nov 2022 15:19:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236385AbiKWUTf (ORCPT ); Wed, 23 Nov 2022 15:19:35 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2673A942E0; Wed, 23 Nov 2022 12:18:34 -0800 (PST) Message-ID: <20221123201624.513863211@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234713; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=HFxpdOK+HSljFgnoRkB4RP8uCX0Txqk1HTDw0OCNhhg=; b=nOgB7LmT+h9XeEvINXogT1ZQCffny2cRZXp+piWF0ZKcl+QZ/EcL4GGaVIWnfCG0XBoLvZ VXZIWCIsh6AZPxHFQL2KAJ1i01+CgBbS0epuZzgrAYSfeb8n5NkQE62eB1c3Jjv0AlYHLO yFgmijScPr1cKgBBRJx+TKf2cb5DTsdgFGyUvofB9gzBW0M6Ht92pY3jMebF/syOwDcv07 RmzOuMI+dIx8DBV9cUYmgaDmVBdpEEuELBwBgxd1cm/MsPXQt+bBYhRPllY6z05lSBAm5F tHhMw37Oa6/nq8OUquMhCNQg2JfDcGGg5mM3C6gMvxuxg9B2vUdFxkOFWMYv/w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234713; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=HFxpdOK+HSljFgnoRkB4RP8uCX0Txqk1HTDw0OCNhhg=; b=UkKfs7gwycRhFPzhJ4lYzcUEJPHttTvKZth1N+MjWiGtMr5YfQWtvNQ3Pfb/URlpgh7hDN 7+eLYSYAHMJMg4CA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 02/17] ARM: spear: Do not use timer namespace for timer_shutdown() function References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:32 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Steven Rostedt (Google)" 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) Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck Reviewed-by: Jacob Keller Acked-by: Arnd Bergmann Acked-by: Viresh Kumar 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 --- arch/arm/mach-spear/time.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c index e979e2197f8e..5371c824786d 100644 --- a/arch/arm/mach-spear/time.c +++ b/arch/arm/mach-spear/time.c @@ -90,7 +90,7 @@ static void __init spear_clocksource_init(void) 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 clock_event_device *evt) 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 clock_event_device *evt) 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 clock_event_device *evt) u16 val; /* stop the timer */ - timer_shutdown(evt); + spear_timer_shutdown(evt); period = clk_get_rate(gpt_clk) / HZ; period >>= CTRL_PRESCALER16; From patchwork Wed Nov 23 20:18:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0A30C433FE for ; Wed, 23 Nov 2022 20:20:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239550AbiKWUUP (ORCPT ); Wed, 23 Nov 2022 15:20:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239044AbiKWUTl (ORCPT ); Wed, 23 Nov 2022 15:19:41 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6ED4E8D485; Wed, 23 Nov 2022 12:18:36 -0800 (PST) Message-ID: <20221123201624.574672568@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234715; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=0NUwUCeX+kvHtS//T3Lp+EdmyILxL/lwp+ttkdi+bV8=; b=PyDJWAMWivv516Xl7tCFqStLetZKAGDN9pcd+jVyzp0dAz1wqDJwb3LsA80GQeki4ekCut CsLp1BL0VBpXX8n+IRAh5+u8VvVAgQTXzAiQCRiurbTVs/GOuAYh8ICNqAYiC8gYQASOll txxuL1Xrqmmb1Io0k8g3Lf09Vr6lruXYzrQaIGloN/djmoJ4KLwvYXv8cxLJ+830eXu6KL XkRmswJMHEw0F/WVqS3771o57ZwEYUaDIYKenJz+Fh4iEh7ZY7tkgb3hqdJVZ7BBtMehe9 A/2rdFe/v2JmVaTx5yleYEH+tsHThN22LcAGYFVeF0ocYK8PZ5L4bwLg5K9J/g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234715; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=0NUwUCeX+kvHtS//T3Lp+EdmyILxL/lwp+ttkdi+bV8=; b=XgBV1MtiBcYw9cOHfc2ILPTLwvzDsMIPqmEpftaoe89V4T27xWKXayuAc8BLmBFGC+nfjB QXUyWMBYijklceBw== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 03/17] clocksource/drivers/arm_arch_timer: Do not use timer namespace for timer_shutdown() function References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:34 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Steven Rostedt (Google)" 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) Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck Reviewed-by: Jacob Keller Acked-by: Marc Zyngier 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 --- drivers/clocksource/arm_arch_timer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index a7ff77550e17..9c3420a0d19d 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -687,8 +687,8 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id) 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_shutdown(const int access, 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, From patchwork Wed Nov 23 20:18:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054208 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DF45C3A59F for ; Wed, 23 Nov 2022 20:20:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233896AbiKWUUS (ORCPT ); Wed, 23 Nov 2022 15:20:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239249AbiKWUTs (ORCPT ); Wed, 23 Nov 2022 15:19:48 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4E3E94A72; Wed, 23 Nov 2022 12:18:38 -0800 (PST) Message-ID: <20221123201624.634354813@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=jQ2gZORL07is72DtXlAGRimkkLqHHcn1aa3jaD5TFbQ=; b=f36afwovLdkt/bqf4IRU0BGDoE5fzvo/VDvwL6PJu2Mh+s99D7wlaMav0MGn+5d2rkaaFc z78cNFGDfmXIVjUDu58QL17rDAHtDmwUnW3j4FcU5qowBNK3yTdRwbbCvIXotFrKZqr3jC hxokt0BKqQTEnEEgA+UV6h4ySRzoyYWlXHiwWDQjEsOkbhj1W5yIYfKPY0Lvn0AcFg8bK1 +vuJoiBcYHufuJQQu/Uj1DpF146Zdd6f/nyBEiq5FrlAnyHa8BTWam9FXeuFsd/OeQM1UX HH4sMAVPw8HzyiJSRDICBS21jomaJ14QdRlOM1fGnycywsiEGQaO65HT9R7jpQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=jQ2gZORL07is72DtXlAGRimkkLqHHcn1aa3jaD5TFbQ=; b=Wtyc63rpuXDakzL82wrwab0u5haPiE3yO5Q30MQKacKsZ25IQ7kTiMswpqhBiDs3Bmecf+ k/JTjeTf1LKh8FAg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 04/17] clocksource/drivers/sp804: Do not use timer namespace for timer_shutdown() function References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:36 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Steven Rostedt (Google)" 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) Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck Reviewed-by: Jacob Keller 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 --- drivers/clocksource/timer-sp804.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c index e6a87f4af2b5..cd1916c05325 100644 --- a/drivers/clocksource/timer-sp804.c +++ b/drivers/clocksource/timer-sp804.c @@ -155,14 +155,14 @@ static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) 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 clock_event_device *evt) 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; From patchwork Wed Nov 23 20:18:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054210 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16997C43219 for ; Wed, 23 Nov 2022 20:20:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239695AbiKWUUm (ORCPT ); Wed, 23 Nov 2022 15:20:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239487AbiKWUUN (ORCPT ); Wed, 23 Nov 2022 15:20:13 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E4C3A7C33; Wed, 23 Nov 2022 12:18:42 -0800 (PST) Message-ID: <20221123201624.706987932@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234718; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=L6OLvdTrTjp+y8rajFPzsnTIgo8oUnw4e56M5qzb6Hk=; b=SqTuXeT5/K63F/GnNVrYmrRtHC4JHzs2kIQhv6uKTdadPmbZ2KwYcbImFcTKnFXfgkqj6W r2r0c8P3CfjjgNx1HS8EhXeodAc44v8FU/EiH3bVHdr+mgcpFrQSXjT0U8Clc69eGxjI8/ JPhW2GQv6UR/l84OjSVHMD7ifS2oIXwBHfwrKoKkrnpn2PIqHDHwovn0RTTR4xxalxnaxa zK3X0wIzE4GVxbwh4as6HsundaNn+fpmqcCJo+NcmwZaZmkiObupUznUjglwtdltWCazbd l8JFgFpzYSyI8RsBZ1xgkgdAvnVb9hfO77zZIH0BYAMpDu+4gRe7AoSHERRzOg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234718; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=L6OLvdTrTjp+y8rajFPzsnTIgo8oUnw4e56M5qzb6Hk=; b=K2mgbma7mgCmvgxL/IrXqyYXQ52uUPOSjuhQ/egNjJvRBNZbLWeMguNKexJ3bTLX8kaPbY qrUdRArbBlUZrTCA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 05/17] timers: Get rid of del_singleshot_timer_sync() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:37 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org del_singleshot_timer_sync() used to be an optimization for deleting timers which are not rearmed from the timer callback function. This optimization turned out to be broken and got mapped to del_timer_sync() about 17 years ago. Get rid of the undocumented indirection and use del_timer_sync() directly. No functional change. Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller --- drivers/char/tpm/tpm-dev-common.c | 4 ++-- drivers/staging/wlan-ng/hfa384x_usb.c | 4 ++-- drivers/staging/wlan-ng/prism2usb.c | 6 +++--- include/linux/timer.h | 2 -- kernel/time/timer.c | 2 +- net/sunrpc/xprt.c | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -155,7 +155,7 @@ ssize_t tpm_common_read(struct file *fil out: if (!priv->response_length) { *off = 0; - del_singleshot_timer_sync(&priv->user_read_timer); + del_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); } mutex_unlock(&priv->buffer_mutex); @@ -262,7 +262,7 @@ ssize_t tpm_common_write(struct file *fi void tpm_common_release(struct file *file, struct file_priv *priv) { flush_work(&priv->async_work); - del_singleshot_timer_sync(&priv->user_read_timer); + del_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); file->private_data = NULL; priv->response_length = 0; --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -1116,8 +1116,8 @@ static int hfa384x_usbctlx_complete_sync if (ctlx == get_active_ctlx(hw)) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - del_singleshot_timer_sync(&hw->reqtimer); - del_singleshot_timer_sync(&hw->resptimer); + del_timer_sync(&hw->reqtimer); + del_timer_sync(&hw->resptimer); hw->req_timer_done = 1; hw->resp_timer_done = 1; usb_kill_urb(&hw->ctlx_urb); --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -170,9 +170,9 @@ static void prism2sta_disconnect_usb(str */ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); - del_singleshot_timer_sync(&hw->throttle); - del_singleshot_timer_sync(&hw->reqtimer); - del_singleshot_timer_sync(&hw->resptimer); + del_timer_sync(&hw->throttle); + del_timer_sync(&hw->reqtimer); + del_timer_sync(&hw->resptimer); /* Unlink all the URBs. This "removes the wheels" * from the entire CTLX handling mechanism. --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -190,8 +190,6 @@ extern int try_to_del_timer_sync(struct # define del_timer_sync(t) del_timer(t) #endif -#define del_singleshot_timer_sync(t) del_timer_sync(t) - extern void init_timers(void); struct hrtimer; extern enum hrtimer_restart it_real_fn(struct hrtimer *); --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1933,7 +1933,7 @@ signed long __sched schedule_timeout(sig timer_setup_on_stack(&timer.timer, process_timeout, 0); __mod_timer(&timer.timer, expire, MOD_TIMER_NOTPENDING); schedule(); - del_singleshot_timer_sync(&timer.timer); + del_timer_sync(&timer.timer); /* Remove the timer from the object tracker */ destroy_timer_on_stack(&timer.timer); --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1164,7 +1164,7 @@ xprt_request_enqueue_receive(struct rpc_ spin_unlock(&xprt->queue_lock); /* Turn off autodisconnect */ - del_singleshot_timer_sync(&xprt->timer); + del_timer_sync(&xprt->timer); return 0; } From patchwork Wed Nov 23 20:18:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054209 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0C29C433FE for ; Wed, 23 Nov 2022 20:20:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239484AbiKWUUl (ORCPT ); Wed, 23 Nov 2022 15:20:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43630 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238765AbiKWUUN (ORCPT ); Wed, 23 Nov 2022 15:20:13 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B5094AB0C0; Wed, 23 Nov 2022 12:18:42 -0800 (PST) Message-ID: <20221123201624.769128888@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234719; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=eCimoLuvktZLfB1uOtjhcgzwdNyr85jFqFSGejnZxME=; b=CD7L6ldoiPUtWAt54rxE0W37G6sMJzvkUpu0CzeC2d09LvqtPSkoD8xTrpbN5utui5RVLx wikpVoqxmsFwfAl3lvMMOY1yfmJKHCsKaMzvG7n5iAYhOGJddhR3f86fKB8R1c0CUJI8hZ 8NcI0p6p+XU8OV6yu98t/zR82Az7tIL1HSZQQU0UL/ki1z9vcaCGW2JY17u2Tz07o3XRIy lnxNbLkht3CJ8veszSeR6zJtFkKsvSz31nUoMWwE3MPgmfxY1THUAqdN32kNeo1OzKdTjL D9eK+z9nRVonc0WfshhEqTrBkLyLzWJkBQdm7QXaqomEGrNjcxkcxxTUYew4Og== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234719; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=eCimoLuvktZLfB1uOtjhcgzwdNyr85jFqFSGejnZxME=; b=BahGPyyTQcd2X5VjiZl2zwqvSBRDAeFNKqDQfbrS+8G+gM7ADytoXTQqiaPoAGO5628h/R mcu8C9E6HfyYMqCA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 06/17] timers: Replace BUG_ON()s References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:39 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Tested-by: Guenter Roeck Reviewed-by: Jacob Keller --- kernel/time/timer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1193,7 +1193,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 +1211,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); @@ -2017,8 +2019,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]); @@ -2035,7 +2035,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); From patchwork Wed Nov 23 20:18:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054212 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A227BC43219 for ; Wed, 23 Nov 2022 20:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239735AbiKWUU7 (ORCPT ); Wed, 23 Nov 2022 15:20:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239563AbiKWUUQ (ORCPT ); Wed, 23 Nov 2022 15:20:16 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 526DAB08D5; Wed, 23 Nov 2022 12:18:43 -0800 (PST) Message-ID: <20221123201624.828703870@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=uiKQn0I9nPUiUnxAwWbEhcHyWBaPF8UxjkEuTg9Q8Ns=; b=cwf7N66VDL2NGoaywe8QW3t43NbMX+NabWic03FNJLQFjyZA5okJ6Zug+CF4mObp+qJP0P t2SJw2LYtIt08/D4zxnb14TVpCS9AV6gXmbtvpLcRAyzIgu9TiaoM6hKOE9HqUz4QIxv3a TvZE0tJN5djsSrMiKl9/lZ2RswuBUQBvvucukNV2icTeoIhmLcZTb0R5Eh+ecSvajA2Lva iiWydGvIurUEX956u4wUQ332ychhfPoK1Hm/wodOfL63s4v1a089oaf4oLLLzvtfV6SzJV hUd8gllFKgUDc4H7mL3Xc2IMw9gDh7RvTU4jHyvaF+q4x+PgmfK3FMOaJQhsmQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=uiKQn0I9nPUiUnxAwWbEhcHyWBaPF8UxjkEuTg9Q8Ns=; b=SZ9Kj+mdCyw+TN/asfE6/oNIty1+yi0OZq0rsT5sKUeTTpKBDGEeTbJdVelS0YMtMmtAll kSaSZdy+JR382zBg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 07/17] timers: Update kernel-doc for various functions References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:40 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The kernel-doc of timer related functions is partially uncomprehensible word salad. Rewrite it to make it useful. Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller --- V2: Refined comments (Steven) V3: Comment updates (Anna-Maria) --- kernel/time/timer.c | 152 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 60 deletions(-) --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1121,14 +1121,16 @@ static inline int } /** - * mod_timer_pending - modify a pending timer's timeout - * @timer: the pending timer to be modified - * @expires: new timeout in jiffies - * - * mod_timer_pending() is the same for pending timers as mod_timer(), - * but will not re-activate and modify already deleted timers. - * - * It is useful for unserialized use of timers. + * mod_timer_pending - Modify a pending timer's timeout + * @timer: The pending timer to be modified + * @expires: New absolute timeout in jiffies + * + * mod_timer_pending() is the same for pending timers as mod_timer(), but + * will not activate inactive timers. + * + * Return: + * * %0 - The timer was inactive and not modified + * * %1 - The timer was active and requeued to expire at @expires */ int mod_timer_pending(struct timer_list *timer, unsigned long expires) { @@ -1137,24 +1139,27 @@ int mod_timer_pending(struct timer_list EXPORT_SYMBOL(mod_timer_pending); /** - * mod_timer - modify a timer's timeout - * @timer: the timer to be modified - * @expires: new timeout in jiffies - * - * mod_timer() is a more efficient way to update the expire field of an - * active timer (if the timer is inactive it will be activated) + * mod_timer - Modify a timer's timeout + * @timer: The timer to be modified + * @expires: New absolute timeout in jiffies * * mod_timer(timer, expires) is equivalent to: * * del_timer(timer); timer->expires = expires; add_timer(timer); * + * mod_timer() is more efficient than the above open coded sequence. In + * case that the timer is inactive, the del_timer() part is a NOP. The + * timer is in any case activated with the new expiry time @expires. + * * Note that if there are multiple unserialized concurrent users of the * same timer, then mod_timer() is the only safe way to modify the timeout, * since add_timer() cannot modify an already running timer. * - * The function returns whether it has modified a pending timer or not. - * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an - * active timer returns 1.) + * Return: + * * %0 - The timer was inactive and started + * * %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 */ int mod_timer(struct timer_list *timer, unsigned long expires) { @@ -1165,11 +1170,18 @@ EXPORT_SYMBOL(mod_timer); /** * timer_reduce - Modify a timer's timeout if it would reduce the timeout * @timer: The timer to be modified - * @expires: New timeout in jiffies + * @expires: New absolute timeout in jiffies * * timer_reduce() is very similar to mod_timer(), except that it will only - * modify a running timer if that would reduce the expiration time (it will - * start a timer that isn't running). + * modify an enqueued timer if that would reduce the expiration time. If + * @timer is not enqueued it starts the timer. + * + * Return: + * * %0 - The timer was inactive and started + * * %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 + * timer would expire earlier than already scheduled */ int timer_reduce(struct timer_list *timer, unsigned long expires) { @@ -1178,18 +1190,21 @@ int timer_reduce(struct timer_list *time EXPORT_SYMBOL(timer_reduce); /** - * add_timer - start a timer - * @timer: the timer to be added + * add_timer - Start a timer + * @timer: The timer to be started * - * The kernel will do a ->function(@timer) callback from the - * timer interrupt at the ->expires point in the future. The - * current time is 'jiffies'. + * Start @timer to expire at @timer->expires in the future. @timer->expires + * is the absolute expiry time measured in 'jiffies'. When the timer expires + * timer->function(timer) will be invoked from soft interrupt context. * - * The timer's ->expires, ->function fields must be set prior calling this - * function. + * The @timer->expires and @timer->function fields must be set prior + * to calling this function. + * + * If @timer->expires is already in the past @timer will be queued to + * expire at the next timer tick. * - * Timers with an ->expires field in the past will be executed in the next - * timer tick. + * This can only operate on an inactive timer. Attempts to invoke this on + * an active timer are rejected with a warning. */ void add_timer(struct timer_list *timer) { @@ -1200,11 +1215,13 @@ void add_timer(struct timer_list *timer) EXPORT_SYMBOL(add_timer); /** - * add_timer_on - start a timer on a particular CPU - * @timer: the timer to be added - * @cpu: the CPU to start it on + * add_timer_on - Start a timer on a particular CPU + * @timer: The timer to be started + * @cpu: The CPU to start it on + * + * Same as add_timer() except that it starts the timer on the given CPU. * - * This is not very scalable on SMP. Double adds are not possible. + * See add_timer() for further details. */ void add_timer_on(struct timer_list *timer, int cpu) { @@ -1240,15 +1257,18 @@ void add_timer_on(struct timer_list *tim EXPORT_SYMBOL_GPL(add_timer_on); /** - * del_timer - deactivate a timer. - * @timer: the timer to be deactivated + * 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.) + * The function only deactivates a pending timer, but contrary to + * del_timer_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 del_timer(struct timer_list *timer) { @@ -1270,10 +1290,19 @@ EXPORT_SYMBOL(del_timer); /** * try_to_del_timer_sync - Try to deactivate a timer - * @timer: timer to delete + * @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 tries to deactivate a timer. Upon successful (ret >= 0) - * exit the timer is not queued and the handler 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) { @@ -1369,23 +1398,19 @@ static inline void del_timer_wait_runnin #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) /** - * del_timer_sync - deactivate a timer and wait for the handler to finish. - * @timer: the timer to be deactivated - * - * This function only differs from del_timer() on SMP: besides deactivating - * the timer it also makes sure the handler has finished executing on other - * CPUs. + * del_timer_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 - * handler. 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. - * - * Note: For !irqsafe timers, you must not hold locks that are held in - * interrupt context while calling this function. Even if the lock has - * nothing to do with the timer in question. Here's why:: + * 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 * ---- ---- @@ -1399,10 +1424,17 @@ static inline void del_timer_wait_runnin * while (base->running_timer == mytimer); * * Now del_timer_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. + * The interrupt on the other CPU is waiting to grab somelock but it has + * interrupted the softirq that CPU0 is waiting to finish. * - * The function returns whether it has deactivated a pending timer or not. + * 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 del_timer_sync(struct timer_list *timer) { From patchwork Wed Nov 23 20:18:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054211 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A265C4332F for ; Wed, 23 Nov 2022 20:20:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239723AbiKWUU4 (ORCPT ); Wed, 23 Nov 2022 15:20:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237373AbiKWUUP (ORCPT ); Wed, 23 Nov 2022 15:20:15 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8D10B043A; Wed, 23 Nov 2022 12:18:44 -0800 (PST) Message-ID: <20221123201624.888306160@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234723; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=0eY7YnzlwSNTQTRTn0uxqikX7ma7laOZXEtpEJOrwxM=; b=4opf8+/GOXjJNOy6hPzmeTt80WMzIFSy8Am96kclq97AQbJnWOAprC4vzZ1RZ9AbWkSeZk 8zxZ4sxeVeoBFgxABFY7ezWo75DXTTNGhM4D5jOMM2E+O2bn+NeGpqfZXBMXe7fEmBdJvK wTJmhUcJZEEsksW+Dkwxwh463sn4aIwrjxMUuHxBlkF9QQB2GcTpqhScr8KqDSwvF2OQfy 8ahBVUYnd/xMAqaBzHyud1lYvkZsmsdMMFwp5r3zMlwNBcALp9chFIOkhiH4aIdZi99Xj4 l/Rge2vagqPxQK11ZT3jUQu2tE7GP+DsyoC3XzfC0xe7A+phaeCOUeMdBjcw9w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234723; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=0eY7YnzlwSNTQTRTn0uxqikX7ma7laOZXEtpEJOrwxM=; b=qUhbnPp1lnq6hw/ZiuMuZPtuw5rIwxw31eQbsu7Um9qICRI4gv+9DhpXmFjAUdmwFAtvnr 9j34rhZTb7lka7Cg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 08/17] timers: Use del_timer_sync() even on UP References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:42 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org del_timer_sync() is assumed to be pointless on uniprocessor systems and can be mapped to del_timer() because in theory del_timer() can never be invoked while the timer callback function is executed. This is not entirely true because del_timer() can be invoked from interrupt context and therefore hit in the middle of a running timer callback. Contrary to that del_timer_sync() is not allowed to be invoked from interrupt context unless the affected timer is marked with TIMER_IRQSAFE. del_timer_sync() has proper checks in place to detect such a situation. Give up on the UP optimization and make del_timer_sync() unconditionally available. Co-developed-by: Steven Rostedt Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org --- include/linux/timer.h | 7 +------ kernel/time/timer.c | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -183,12 +183,7 @@ extern int timer_reduce(struct timer_lis extern void add_timer(struct timer_list *timer); extern int try_to_del_timer_sync(struct timer_list *timer); - -#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 +extern int del_timer_sync(struct timer_list *timer); extern void init_timers(void); struct hrtimer; --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1396,7 +1396,6 @@ static inline void timer_sync_wait_runni 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. * @timer: The timer to be deactivated @@ -1477,7 +1476,6 @@ int del_timer_sync(struct timer_list *ti return ret; } EXPORT_SYMBOL(del_timer_sync); -#endif static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *), From patchwork Wed Nov 23 20:18:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054214 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 276BBC47088 for ; Wed, 23 Nov 2022 20:21:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239775AbiKWUV2 (ORCPT ); Wed, 23 Nov 2022 15:21:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239403AbiKWUUf (ORCPT ); Wed, 23 Nov 2022 15:20:35 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EED97BF5AF; Wed, 23 Nov 2022 12:18:54 -0800 (PST) Message-ID: <20221123201624.954785441@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234724; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=9aovE9SsY83ZBBgWbgO0H2UxzRJSCD39AJ6NU6FG1LY=; b=ap/DBinmESrU5PswQAz1fTDCTpjoban93gqTgfXUWnTbp8XWAhpO72DbRtjnNva4DBwNOb CnLdVcgK4/TtbLESHnQi2GKu8nIxRqul2jXQpqjiGqwZbfVpDdeL1aY8x6YwtIaPCqnffG wYXfFTzorCV9JTe74qqlMfAoIZf2ukwIFh0AQdEYxeBkebPl0KMtIXKir/B9bMdARWilTK ZSWWnQbRZauVzwd1CoGAX5MLnPfhQIyc68Q+6UCNXvxW0WIZPYvvbm8X/WkasvD2oBZ/cI T0Fha2YjLLe421KfwwjXDU8vJT6BbmK1Vsu87Xx3Eia+wru7LVPAxEPT7rwVtg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234724; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=9aovE9SsY83ZBBgWbgO0H2UxzRJSCD39AJ6NU6FG1LY=; b=rGvZGpizAO3Cf9dY+7n2noKeNPiOVblL+DuS0Y0BANN1X2CFnzbwW+MuPusJxc0++c9u8T VJFOGDipEaiGB9DA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 09/17] timers: Rename del_timer_sync() to timer_delete_sync() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:44 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The timer related functions do not have a strict timer_ prefixed namespace which is really annoying. Rename del_timer_sync() to timer_delete_sync() and provide del_timer_sync() as a wrapper. Document that del_timer_sync() is not for new code. Signed-off-by: Thomas Gleixner Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jacob Keller Tested-by: Guenter Roeck --- include/linux/timer.h | 15 ++++++++++++++- kernel/time/timer.c | 18 +++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -183,7 +183,20 @@ extern int timer_reduce(struct timer_lis 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); +extern int timer_delete_sync(struct timer_list *timer); + +/** + * del_timer_sync - Delete a pending timer and wait for a running callback + * @timer: The timer to be deleted + * + * See timer_delete_sync() for detailed explanation. + * + * Do not use in new code. Use timer_delete_sync() instead. + */ +static inline int del_timer_sync(struct timer_list *timer) +{ + return timer_delete_sync(timer); +} extern void init_timers(void); struct hrtimer; --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1083,7 +1083,7 @@ static inline int /* * We are trying to schedule the timer on the new base. * However we can't change timer's base while it is running, - * otherwise del_timer_sync() can't detect that the timer's + * otherwise timer_delete_sync() can't detect that the timer's * handler yet has not finished. This also guarantees that the * timer is serialized wrt itself. */ @@ -1261,7 +1261,7 @@ EXPORT_SYMBOL_GPL(add_timer_on); * @timer: The timer to be deactivated * * The function only deactivates a pending timer, but contrary to - * del_timer_sync() it does not take into account whether the timer's + * 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. @@ -1397,7 +1397,7 @@ static inline void del_timer_wait_runnin #endif /** - * del_timer_sync - Deactivate a timer and wait for the handler to finish. + * 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, @@ -1419,10 +1419,10 @@ static inline void del_timer_wait_runnin * spin_lock_irq(somelock); * * spin_lock(somelock); - * del_timer_sync(mytimer); + * timer_delete_sync(mytimer); * while (base->running_timer == mytimer); * - * Now del_timer_sync() will never return and never release somelock. + * 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. * @@ -1435,7 +1435,7 @@ static inline void del_timer_wait_runnin * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int del_timer_sync(struct timer_list *timer) +int timer_delete_sync(struct timer_list *timer) { int ret; @@ -1475,7 +1475,7 @@ int del_timer_sync(struct timer_list *ti return ret; } -EXPORT_SYMBOL(del_timer_sync); +EXPORT_SYMBOL(timer_delete_sync); static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *), @@ -1497,8 +1497,8 @@ static void call_timer_fn(struct timer_l #endif /* * Couple the lock chain with the lock chain at - * del_timer_sync() by acquiring the lock_map around the fn() - * call here and in del_timer_sync(). + * timer_delete_sync() by acquiring the lock_map around the fn() + * call here and in timer_delete_sync(). */ lock_map_acquire(&lockdep_map); From patchwork Wed Nov 23 20:18:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054216 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 022E7C4332F for ; Wed, 23 Nov 2022 20:21:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239822AbiKWUVn (ORCPT ); Wed, 23 Nov 2022 15:21:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239503AbiKWUUl (ORCPT ); Wed, 23 Nov 2022 15:20:41 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D42EFC4B53; Wed, 23 Nov 2022 12:18:59 -0800 (PST) Message-ID: <20221123201625.015535022@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234726; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=5NDAS6/az4AeI8J230HSj0OuzxPfO5AK/cHGCm94sf4=; b=ZxiB0MoKEhrDs6JnIu4R9zZvIUheLbc2riXKkak0s/kMJ+z/QTRv1YfxkAZT98MHKqvWDR JnwkfvYUgLO/yfLcHQDwbiPyKvRuiR9D2qGd2UgRPYFTDg8EB2PieJb1UVUdLJlgJ0RDqq Hw1PJgpylIREi/Q3si0wBnhaA3UM/iFFSUDDR+ES9CYcM7jJZYunTkw5YcpsAT20d5kDvY DE5w09yfOAp0lIiNXeoD35mQ98aBST+T5Ranv5Y6gbZL04Ro8iRo6/VR/5HHTQ+q24IIvU KQ+bQJsSBV13Sh6fzLn9iUEHtEc6uc5TeE7yR9BqTS2aSW3WAJF1A21dIEktyQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234726; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=5NDAS6/az4AeI8J230HSj0OuzxPfO5AK/cHGCm94sf4=; b=kxNsdontzmcLltKzlyA3jGnTy3ggg6p/i1u+bkF4W4Duiy/6aKUGPskh4Wph+aDmjevQ+j Q3HnhWipW9NtjHAA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 10/17] timers: Rename del_timer() to timer_delete() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:45 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The timer related functions do not have a strict timer_ prefixed namespace which is really annoying. Rename del_timer() to timer_delete() and provide del_timer() as a wrapper. Document that del_timer() is not for new code. Signed-off-by: Thomas Gleixner Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jacob Keller Tested-by: Guenter Roeck --- include/linux/timer.h | 15 ++++++++++++++- kernel/time/timer.c | 6 +++--- 2 files changed, 17 insertions(+), 4 deletions(-) --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -169,7 +169,6 @@ static inline int timer_pending(const st } 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); @@ -184,6 +183,7 @@ 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); /** * del_timer_sync - Delete a pending timer and wait for a running callback @@ -198,6 +198,19 @@ static inline int del_timer_sync(struct return timer_delete_sync(timer); } +/** + * del_timer - Delete a pending timer + * @timer: The timer to be deleted + * + * See timer_delete() for detailed explanation. + * + * Do not use in new code. Use timer_delete() instead. + */ +static inline int del_timer(struct timer_list *timer) +{ + return timer_delete(timer); +} + extern void init_timers(void); struct hrtimer; extern enum hrtimer_restart it_real_fn(struct hrtimer *); --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1257,7 +1257,7 @@ void add_timer_on(struct timer_list *tim EXPORT_SYMBOL_GPL(add_timer_on); /** - * del_timer - Deactivate a timer. + * timer_delete - Deactivate a timer. * @timer: The timer to be deactivated * * The function only deactivates a pending timer, but contrary to @@ -1270,7 +1270,7 @@ EXPORT_SYMBOL_GPL(add_timer_on); * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int del_timer(struct timer_list *timer) +int timer_delete(struct timer_list *timer) { struct timer_base *base; unsigned long flags; @@ -1286,7 +1286,7 @@ int del_timer(struct timer_list *timer) return ret; } -EXPORT_SYMBOL(del_timer); +EXPORT_SYMBOL(timer_delete); /** * try_to_del_timer_sync - Try to deactivate a timer From patchwork Wed Nov 23 20:18:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA20FC433FE for ; Wed, 23 Nov 2022 20:21:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239766AbiKWUV1 (ORCPT ); Wed, 23 Nov 2022 15:21:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239393AbiKWUUf (ORCPT ); Wed, 23 Nov 2022 15:20:35 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80F62BEAF7; Wed, 23 Nov 2022 12:18:54 -0800 (PST) Message-ID: <20221123201625.075320635@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234727; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=1FRJAnaRsIw8Csy6BN8zPa3bMyc93id2b+gcGKDCm00=; b=IXyrE+00qGqMETjQqESePRw375/eBfj8izUY+WP2S46hkh9EmJWNXjPOa+JUw1RIfSge03 0iJNCFC8v/M6xgGo5GXP+NourJj2LSVZpp2hsQQWYD3YQTrx2ziJhaxNdH/38Tky7VzLqp Q+nCOMmvhlYzxtFjo68G5Mw+ryPSYq9/BNkCyJ88B4DnDVd3GIIoAtuvTMCyC8FWZ1tkdB NXE1IoXRoM6+IC5KXSSjoim3i8EYp27ljTaHMicOqKSifeqf3sTDF2Olci2oKhXvRouSVR AHwIvvmEjdDBZO2xTUHBROdQ+rNxoHrRhetUbi/zA7wJQpEsMTmfda2i3MdX+g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234727; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=1FRJAnaRsIw8Csy6BN8zPa3bMyc93id2b+gcGKDCm00=; b=Pu+mkN/t+nhUuX+yQYi202ggUEJnXOuDNTmDeA13+CVO6vt6KpN3+Fqef2TWfYqAxOGPvX 1TsBfIFZ+tCQb9CQ== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 11/17] Documentation: Replace del_timer/del_timer_sync() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:47 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Adjust to the new preferred function names. Suggested-by: Steven Rostedt Signed-off-by: Thomas Gleixner Reviewed-by: Jacob Keller --- 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 @@ If you want to destroy the entire collec 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 @@ If 0, it means (in this case) that it is 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 @@ If 0, it means (in this case) that it is 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 handle this case. 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 @@ Se volete eliminare l'intera collezione 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 @@ rimosso. Se 0, significa (in questo caso 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 @@ rimosso. Se 0, significa (in questo caso 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之间没有不同的行为,在你� static void __exit test_exit(void) { - del_timer_sync(&test_timer); + timer_delete_sync(&test_timer); } module_init(test_init); From patchwork Wed Nov 23 20:18:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054215 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9489C433FE for ; Wed, 23 Nov 2022 20:21:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239426AbiKWUVb (ORCPT ); Wed, 23 Nov 2022 15:21:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239433AbiKWUUi (ORCPT ); Wed, 23 Nov 2022 15:20:38 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 45A0D9736C; Wed, 23 Nov 2022 12:18:58 -0800 (PST) Message-ID: <20221123201625.135055320@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234729; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=ccJ29r5vqAaRgINs2msmvqSSxmrjUJnOHkZaGMFg8is=; b=4bW1VSWIrpc1KgCz7LKcdcS7zmyLmguGg0VPiGvul2FfmChJ3jM89Q/C+ym4ZakocLwAHV 5wZ+ClovyYrl6jm/ZetexYcRBbk+ChmOA3tNYXHgt7SH+QCHmeLyzPiMtpTN3AFgbZfLut RFFON/3z5TIsg/jMfigEEeAD4hWmCFkhroxtKZq0B96zBUrDOWhWC0U4Btb1JI69I8wz+I 4MIPJWHVt1+esn3UsaRgNp4DhBPvmzLqUEXQHAUv5JN7eKPz+rgAaBQgM5pmOE4abICY7h ZRYXxmsmc0rTo9phNPfBwqGY0hos83vUhxdWXyB/d1xUW7u9tMWa56lqCcSxuA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234729; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=ccJ29r5vqAaRgINs2msmvqSSxmrjUJnOHkZaGMFg8is=; b=rF8JhyqUNHaMqS87ok38FB3NdIkEIkfHD087elnmB2MsmHLVtEkLWwsNwr2YOkNaKxqyH/ yt5XRa2oBayJZ2BQ== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 12/17] timers: Silently ignore timers with a NULL function References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:48 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 NULLL, 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 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 Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org --- V2: Use continue instead of return and amend the return value docs (Steven) V3: Changelog and comment updates (Anna-Maria) --- 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 @@ static inline int 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 @@ static inline int * 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 @@ static inline int } } 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 @@ static inline int * 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 is 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); From patchwork Wed Nov 23 20:18:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B41CEC433FE for ; Wed, 23 Nov 2022 20:21:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239835AbiKWUVr (ORCPT ); Wed, 23 Nov 2022 15:21:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239686AbiKWUUl (ORCPT ); Wed, 23 Nov 2022 15:20:41 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D58A2C4B6C; Wed, 23 Nov 2022 12:18:59 -0800 (PST) Message-ID: <20221123201625.195147423@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234731; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=+lVgmpxcAPl3Q4fzabjM7MN3q05Moh/yWkF9Dw/n40w=; b=IuDPGDVllgKaBJ8LK55OjzSskUS+6JYWYuLCOyEb65H8yiH1sCohYdvTipMVAk3KKXhRQX 6uTOmW3GJAUq2YvksDPXz8bKfIm/7Jut6+UNeBada5bgYudgLkdjt9ezo3YaVv4V10Y3AC Um6tbvBpq989txHjJvYXIdDyHjBSdXpjBK1Dzcw6A0ekh7yBoIUyJL+ZWCAtnOtSyp9H/M tNYo7COedzPgS+29CeS0ftnFseU2lMk0DTGxBMlZOuYSF3UaTDBYlArS8l+zYAVQbwY2Ip Dgp6T2+AlEBq6DVol2wcGu8e8A7oOi47Gh+WlHPZw/jNnUl/4UM2LYE6teVeKw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234731; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=+lVgmpxcAPl3Q4fzabjM7MN3q05Moh/yWkF9Dw/n40w=; b=jIziz4S3ZLk12Ej+2xdagb98G1VHEeGZcLov76YTdqop8+3X2is5fgsJ7Tftn3I/LLQkyt 7m7Elx9z4jS1RqDw== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 13/17] timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown mode References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:50 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org --- V3: Changelog updates (Anna-Maria) --- 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 @@ void add_timer_on(struct timer_list *tim 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 - * ---- ---- - * - * call_timer_fn(); - * base->running_timer = mytimer; - * spin_lock_irq(somelock); - * - * 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 + * ---- ---- + * + * call_timer_fn(); + * base->running_timer = mytimer; + * spin_lock_irq(somelock); + * + * 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, From patchwork Wed Nov 23 20:18:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054239 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA4DBC3A59F for ; Wed, 23 Nov 2022 20:22:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239547AbiKWUWL (ORCPT ); Wed, 23 Nov 2022 15:22:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239515AbiKWUUm (ORCPT ); Wed, 23 Nov 2022 15:20:42 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C864C5624; Wed, 23 Nov 2022 12:19:00 -0800 (PST) Message-ID: <20221123201625.253883224@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234732; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=udvsR5bjuwgPwBaIW6cLLqel7viRSYpUL0eeQfJ9dPs=; b=EYYiM3G1ql1WLLhz88gV5SUylrr04Gptf6coXwEUFNo3en3WLfueHL3ybMm7AQPcg8Tb4H MaKQ/T5O97cGCvjQMBSt5s6mhlnXqJ2PlkSkb7KdjMwCXATL/qFv8Sd1jn9g21I6TbvBPI uasTp1s9kwVuWLQNAVnUL8KwqDyQSExzdtAJdfpzZoMaPnQK2NyOk+fnUlaak/Pi5+xy8o 315PVVPMaOWersP8t87+df0a0CcuklJRB5s2Dd5vns8o/2PHDChFsyIH78n0MwdFLj38A/ 5E2SE19lKDjTubYVXZ9xeTH9PhlFRLn4T/nqQv2fNn81JMkvA3+w99qa1SXyQA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234732; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=udvsR5bjuwgPwBaIW6cLLqel7viRSYpUL0eeQfJ9dPs=; b=ape3dlhBdUUmZO0KPhO2Ej6zKSIhb+ylm1KT+nUCV1oR8r6HC3CVTSnH8LUYZ3uPnRTIKc 454md67Y8G3dIrBA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 14/17] timers: Add shutdown mechanism to the internal functions References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:52 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org --- V2: Add missing commata (Steven) V3: Changelog updates (Anna-Maria) --- kernel/time/timer.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 9 deletions(-) --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1297,14 +1297,21 @@ void add_timer_on(struct timer_list *tim EXPORT_SYMBOL_GPL(add_timer_on); /** - * __timer_delete - Internal function: Deactivate a timer. + * __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; @@ -1312,9 +1319,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 @@ EXPORT_SYMBOL(timer_delete); */ 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); From patchwork Wed Nov 23 20:18:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054240 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1995C3A59F for ; Wed, 23 Nov 2022 20:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239596AbiKWUWT (ORCPT ); Wed, 23 Nov 2022 15:22:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239629AbiKWUVZ (ORCPT ); Wed, 23 Nov 2022 15:21:25 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E375C80FB; Wed, 23 Nov 2022 12:19:12 -0800 (PST) Message-ID: <20221123201625.314230270@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234734; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=l06tkiyNJfvakxKC301njZoUS4DKvoyv3mRcr5swQ2g=; b=FHwqYIJnYhqK+TPMxKXc1V8Lb7jTEvVY9sk032+OIfTK84eK7wTgSvZPeyYFzRlmgS966A w5/NArKqpzFRD4D8q+DMPvIfU+oaRDQX3IvPOtNM/evAf2d8kHkRxdMhOx0qKychul0JzX mP8JYXz7Vt8DlRmXC3poSqD8GurVjJpNjrj47thLOSw8kbw8LQDn0t0NuznMtAYkYc3kHf E7e4Nr1r7lxIBLcD5oq+1RMGzdGRRJpGOOGblQe5jmu+yXLc6zxakXSBLmXKyY/8fX4gym v7CXXAqRb/hXh2VZqV10v9FYQhNynQmcHliJUuJjo4IS3Vo0VYVGSerBFKCX9g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234734; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=l06tkiyNJfvakxKC301njZoUS4DKvoyv3mRcr5swQ2g=; b=Sl5pjevgV6G9tNTsI5MNFCU9d/gbe9f0TTg05VIKFB+PQ86KliFQl2odtjadtQg7+ZRtIV 5pU5HuMroU2i2xDg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 15/17] timers: Provide timer_shutdown[_sync]() References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:53 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org --- V3: Changelog and comment updates (Anna-Maria) --- 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) From patchwork Wed Nov 23 20:18:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054238 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 326E2C4332F for ; Wed, 23 Nov 2022 20:22:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236307AbiKWUWK (ORCPT ); Wed, 23 Nov 2022 15:22:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239592AbiKWUVX (ORCPT ); Wed, 23 Nov 2022 15:21:23 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56D0AC78CC; Wed, 23 Nov 2022 12:19:11 -0800 (PST) Message-ID: <20221123201625.375284489@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234735; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=8mCfHxFOZzbOCsR313/bDzGhRTnb1fj4Q7VlJBNG0jE=; b=gsOHJxPeeeijJQ12VQfyqzGPX8xgyqZ96mWswxQCmi0j/GQ/N8eEa/pq5VJHwopx9L3PEG LB5I2kBB3h2QVSODmoCyUGI/dS7geEHzN74Ak1KEo9W5UkS/hf6yV8lITtey/5T7dJTemI KleqRuSumcCg2MAH+nAd6Bpi+YQ4wVPn8xj1+IvaSmpzZ13efp5MdqdCTa2mjb3d+MGJcC F9j8c9wv+5EJV9gOoPhtkzPnqEUEsGXHea+yEPHZeKkeKWOb5pJsPaVTKjLPzucEKimo4l 3YyEaUFT7VqhaItBqAyU2VfCbZp9nc0nECPk9TQsmRXmvABOWcbborbkjpn1FQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234735; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=8mCfHxFOZzbOCsR313/bDzGhRTnb1fj4Q7VlJBNG0jE=; b=nN2gBcA8qa+c86/g9eNv5e51qKePiLEGDO3stJq4tkr3jZGsTDWvbRhR0cOUM6VloCC2XF P8Ox1KfFtz+yQJBA== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 16/17] timers: Update the documentation to reflect on the new timer_shutdown() API References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:55 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Steven Rostedt (Google)" 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) Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Link: https://lore.kernel.org/r/20221110064147.712934793@goodmis.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 handle this case. +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之间没有不同的行为,在你� static void __exit test_exit(void) { - timer_delete_sync(&test_timer); + timer_shutdown_sync(&test_timer); } module_init(test_init); From patchwork Wed Nov 23 20:18:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 13054241 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11623C43219 for ; Wed, 23 Nov 2022 20:22:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239730AbiKWUWf (ORCPT ); Wed, 23 Nov 2022 15:22:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239361AbiKWUV0 (ORCPT ); Wed, 23 Nov 2022 15:21:26 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2E80C769B; Wed, 23 Nov 2022 12:19:13 -0800 (PST) Message-ID: <20221123201625.435907114@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669234737; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=N5rjif6fyxnP/Qgbwg5ZMeD/njPbRjLjFEtdr1g8NrQ=; b=R9QHOKD307W6xOOboyxsH4Y9NpQA+cS0rm9nYLPCkqLpbXXlf7QKZk/un/aTDPSM8r8ke0 WHn6izB5oy4rGA83r+5+1TwRlumiU+VVFCU8PQK8GrvvfAcNBSA2v5ocQMfB0A6kU6r3JH qEpMYrGt9z+IPS6/Ctb6ddMTtTTo4VoAS74Ct/ec6emH6p+fQ1SzrtEc9vBL6znzRNP713 FpXmcKZlEU0TzqQmwK+wUAzgNEB/g7Cib+bRz2y6AMYGMbjRPVXh1r6MxInXm4e1qCGRgi CpDwasqC/RCHLMlEbhVfXMvArunDJPBguejkD+XStLfBV3N/TqEeBco5rIT2Bw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669234737; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=N5rjif6fyxnP/Qgbwg5ZMeD/njPbRjLjFEtdr1g8NrQ=; b=2dJK9SFpNO7GBTAPIsBlJ30G65FIbTDXFF2qtscws/0M6SmS23TaGhsCxRNhPmvqmPY9+U LNq7gAjOreuCrOBg== From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Steven Rostedt , Anna-Maria Behnsen , Peter Zijlstra , Stephen Boyd , Guenter Roeck , Andrew Morton , Julia Lawall , Arnd Bergmann , Viresh Kumar , Marc Zyngier , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, Jacob Keller Subject: [patch V3 17/17] Bluetooth: hci_qca: Fix the teardown problem for real References: <20221123201306.823305113@linutronix.de> MIME-Version: 1.0 Date: Wed, 23 Nov 2022 21:18:57 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Acked-by: Luiz Augusto von Dentz Cc: Marcel Holtmann Cc: Johan Hedberg Cc: linux-bluetooth@vger.kernel.org Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/all/87iljhsftt.ffs@tglx --- 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 @@ -696,9 +696,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);