Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp4808792rwb; Sun, 13 Nov 2022 14:26:14 -0800 (PST) X-Google-Smtp-Source: AA0mqf6AkoiyCjmxjNFQB+6EDhWJXes4X/KYNM5hziJvXnnmxMu0Dvt/TS7LXHRtxCj16wYpR7rN X-Received: by 2002:a65:5bc9:0:b0:46f:ec9c:b239 with SMTP id o9-20020a655bc9000000b0046fec9cb239mr9779247pgr.33.1668378374011; Sun, 13 Nov 2022 14:26:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668378374; cv=none; d=google.com; s=arc-20160816; b=Ovi/CofoKZBkUkWK2pHxp3yo4BeSlUIZnxc+WbhFG6DAGUOolR8r56FoiOpmVMaRGT jP70vZ1N5DE/Cd7HMGiFF5scB+KYiOxvzZll73QcXfgOC1pKBAUL7A3hWpDedYoltEya 09SNLDvCVtajuh1h+2pF7FnLHohysu+NurgVP4qfcbGsd/O9MlmPBBhpgIzF2+xUnIME FGNXCNWxGyt3nykiiE3PFArGt1jyL5N4OuMHN65zM8knYOAIpvJWq1VA81M3tncGZgvQ DG2KWeyRXSvaFBazvJGwwYnGtFtS9OIcxAzpSsVhnwVsBP7ROQ/XmNKI1Bqy+J0HSVcv Fk2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:dkim-signature:dkim-signature:from; bh=EFuhDtI5E596clgtvdQHNPXYyvIgW5iwp/YHGywCpts=; b=qqZzBgO72Av2BAYo03xaI8havVY5F3F3TTvQ8DnCsr3FN34KHn36VzHsjenseSdDwn QgJbhhqUJ2A2hs28nc4CKBsVTjWxsPQGSXC5K1qkq5xJre6aRvGVvttfqI7UcBT7WZ2A 8P+1FGWdpqsdoDp6fIsFRYEH1bIar785QX7PO4LkLmACBKhVx/1s6g2o6lgbYQdxmwAe hWmCAmcSpcLnTWkLqbEpT+81Z1dNnBzTscShqOVOga+ZQBOvMUncqShUFQchLjiWHYxq s5Fo0+eVtMJ81FjY3J8+H7vRKDH6rtTQT/ppOHhFhb0iMpZhOoPiOir64Fb71DVAGYKs c/PA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=byDq0bIQ; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ch12-20020a056a00288c00b00545c1d801d7si7254953pfb.364.2022.11.13.14.26.01; Sun, 13 Nov 2022 14:26:14 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=byDq0bIQ; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235443AbiKMWUg (ORCPT + 90 others); Sun, 13 Nov 2022 17:20:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229692AbiKMWUe (ORCPT ); Sun, 13 Nov 2022 17:20:34 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD70EE0C8 for ; Sun, 13 Nov 2022 14:20:33 -0800 (PST) From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1668378032; 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: in-reply-to:in-reply-to:references:references; bh=EFuhDtI5E596clgtvdQHNPXYyvIgW5iwp/YHGywCpts=; b=byDq0bIQ9u99fuRPJlc3gY02GidmLCRGFnohb1gpX50S9n8MyXhwrwRzaWEeUBxsCKyufT BeJRStFWEmi6+Ix/CR5afdF8d/UfgE3Mvv72+mHs01erjoCCMuBjvO3h9UPthUVXpt1GjY MEgho1g+ucfG33Y2OG3DaGmGkLRlDNpzFs1LWMiI2e71wHLww1wGuuGv/AYxGEDY98Vg/P TJFn8bUlmD4aHh2x9+69M08ceMf62boRvO0UeB6T1NpRavVSoV5ie1+sDFDmkj1CfoLkYR gjIieybtiWZDc88J9l8fMJb2GG2T+XlTCb8x5xClKewh5+FVHSLoxT7Z5aeRdQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1668378032; 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: in-reply-to:in-reply-to:references:references; bh=EFuhDtI5E596clgtvdQHNPXYyvIgW5iwp/YHGywCpts=; b=f3eZRMahdQyVAO1pbGBZ1MOZg9Ps/OpJJ7MyT7JJwt9mR9RfQVi6G8FHxgQDP0UgRZBhGL MmMCD1hhKAZzDjCQ== To: Steven Rostedt , linux-kernel@vger.kernel.org Cc: Linus Torvalds , Stephen Boyd , Guenter Roeck , Anna-Maria Gleixner , Andrew Morton , Julia Lawall Subject: Re: [PATCH v6 5/6] timers: Add timer_shutdown() to be called before freeing timers In-Reply-To: <20221110064147.529154710@goodmis.org> References: <20221110064101.429013735@goodmis.org> <20221110064147.529154710@goodmis.org> Date: Sun, 13 Nov 2022 23:20:31 +0100 Message-ID: <87a64uts28.ffs@tglx> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Nov 10 2022 at 01:41, Steven Rostedt wrote: > From: "Steven Rostedt (Google)" $Subject: !!@*&^*&^@! > Before a timer is to be freed, it must be shutdown. But there are some > locations were timer_shutdown_sync() can not be called due to the context > the object that holds the timer is in when it is freed. locations? This is not about locations, it's about contexts. And please provide a proper example for such a context. > For cases where the logic should keep the timer from being re-armed but > still needs to be shutdown with a sync, a new API of timer_shutdown() is > available. "Needs to shutdown with a sync"? "is available"? Try again with comprehensible explanations. > This is the same as del_timer() except that after it is called, the > timer can not be re-armed. If it is, a WARN_ON_ONCE() will be > triggered. > > The implementation of timer_shutdown() follows the timer_shutdown_sync() > method of using the same code as del_timer() but will pass in a boolean > that the timer is about to be freed, in which case the timer->function is > set to NULL, just like timer_shutdown_sync(). That's complete useless information for a changelog. We can see that from the patch itself, no? Changelogs are about context and the problem the patch tries to solve, not about implementation details. > +/** > + * del_timer - deactivate a timer. > + * @timer: the timer to be deactivated See previous comments about uppercase. > + * del_timer() deactivates a timer - this works on both active and inactive > + * timers. How so? What "works"? What's the work done on an inactive timer? Also this lacks documentation that this function is fundamentally racy against a concurrent rearm. > + * 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.) See previous comment about return value documentation. > + */ > +static inline int del_timer(struct timer_list *timer) > +{ > + return __del_timer(timer, false); > +} > + > +/** > + * timer_shutdown - deactivate a timer and shut it down > + * @timer: the timer to be deactivated > + * > + * timer_shutdown() deactivates a timer - this works on both active > + * and inactive timers, and will prevent it from being rearmed. This needs some further explanation especially vs. the function pointer being set to NULL. Which means that in case that the timer is not freed and reused later on it needs to be initialized again. Which is btw lacking from timer_shutdown_sync() too. > + * The function returns whether it has deactivated a pending timer or not. > + * (ie. timer_shutdown() of an inactive timer returns 0, > + * timer_shutdown() of an active timer returns 1.) > + */ > +static inline int timer_shutdown(struct timer_list *timer) > +{ > + return __del_timer(timer, true); > +} > + > /* > * The jiffies value which is added to now, when there is no timer > * in the timer wheel: > diff --git a/kernel/time/timer.c b/kernel/time/timer.c > index 111a3550b3f2..7c224766065e 100644 > --- a/kernel/time/timer.c > +++ b/kernel/time/timer.c > @@ -1240,18 +1240,7 @@ void add_timer_on(struct timer_list *timer, int cpu) > } > EXPORT_SYMBOL_GPL(add_timer_on); > > -/** > - * del_timer - deactivate a timer. > - * @timer: the timer to be deactivated > - * > - * del_timer() deactivates a timer - this works on both active and inactive > - * timers. > - * > - * The function returns whether it has deactivated a pending timer or not. > - * (ie. del_timer() of an inactive timer returns 0, del_timer() of an > - * active timer returns 1.) > - */ Instead of blurbing about invoking __del_timer() with free=true in the changelog you could have kept the kernel doc here and/or added some useful comment to the code below. But... > -int del_timer(struct timer_list *timer) > +int __del_timer(struct timer_list *timer, bool free) > { > struct timer_base *base; > unsigned long flags; > @@ -1262,12 +1251,18 @@ int del_timer(struct timer_list *timer) > if (timer_pending(timer)) { > base = lock_timer_base(timer, &flags); > ret = detach_if_pending(timer, base, true); > + if (free) > + timer->function = NULL; > + raw_spin_unlock_irqrestore(&base->lock, flags); > + } else if (free) { > + base = lock_timer_base(timer, &flags); > + timer->function = NULL; > raw_spin_unlock_irqrestore(&base->lock, flags); > } ... this function is a concurrency disaster: CPU0 CPU1 timer_shutdown(timer) __del_timer(timer, free=true) // timer is not pending .... } else if (free) mod_timer() lock_timer(timer); lock_timer(timer) enqueue_timer(timer); unlock_timer(timer); timer->function = NULL; unlock_timer(timer); //timer expires lock_timer(timer); fn = timer->function; unlock_timer(timer); fn(timer); <--- NULL pointer dereference So you "solve" the existing problem by introducing one which is even more horrible to debug, right? Let me go back to the timer_shutdown_sync() variant and figure out whether that one is at least not borked in the same way. Thanks, tglx