Message ID | 20230225032716.3320124-1-joel@joelfernandes.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp1295787wrd; Fri, 24 Feb 2023 19:33:00 -0800 (PST) X-Google-Smtp-Source: AK7set9MKI3O7hJCfw34XgYOWRMNdZ7SQFW2Oe4yZETFvzQ4v9rMKiW9HHE85itnG84tsTyp74cP X-Received: by 2002:a17:902:d50c:b0:19c:e9c4:cc13 with SMTP id b12-20020a170902d50c00b0019ce9c4cc13mr2143623plg.25.1677295979970; Fri, 24 Feb 2023 19:32:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677295979; cv=none; d=google.com; s=arc-20160816; b=oPMWkAFWqAdK7oZMJbKk37bbR85gV1F2sxavX8qg45K+4SD2T520aO/NDRtMxqbi5A K7yv/4pls7NAIgIP6EmlGe/yeaeekxQBKhzEqeutYkMZkFS7Dg3xoSej1OzVsOmrG3s0 MUxqDSCQNjkKeQq05skgLl0EjB8RuWYQipzMCrCoNoMPnQWwhn5ZJRTleOogp4XjnWKn AbgbWaDeEB+t0EQyR3sGVGRL+t5hvXpi/d4JMpwbhxQBq1TBe38X+vPuuPglq/xxewyc S2TAE3sDsfRciUAll77Az8VCsHB/F9Q0Ftn9FanvqndGHlAlCRRT99euoWq10MKEc6nK /8Aw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=RHZn/4jVwdf9ks/OwO+bD/mVMTUWc6RD0o1MFPaoins=; b=oRTKhvY0GsWOZrdqHi0Zc6NTChZHkxu0p665hkthSx9dAwoLbidcMOcl/3KJrV2NMg zck9nhw66pdU/9mUowUQlBFYq1shU/EGaQPHQLaXm7p2PkJ6J+I/3UvZGK31c3x6qBhh YUvNSFks6OUpW0v/xhslfLSkdijd+DH7Adp/CKeA9GXJWBk3JlzC0vWhTUbiDiWCkd9x dZhoUcvbupIO2+6AqlXXIKeI1dcvU5NKqbmp4a8PBw+joRp3F5pk7EpUyKCpAOi5mazj qdF5JEvyKuNx5nuclYUZJGB6zOsr6J2oh5DHfmlKItMU8CV49ecCLxzfHR2dc/PXjkKa zy0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@joelfernandes.org header.s=google header.b="uWe2Eq/p"; 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 Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id jc7-20020a17090325c700b0019cac966629si669134plb.245.2023.02.24.19.32.45; Fri, 24 Feb 2023 19:32:59 -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=@joelfernandes.org header.s=google header.b="uWe2Eq/p"; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229534AbjBYD1Z (ORCPT <rfc822;guoshuai5156@gmail.com> + 99 others); Fri, 24 Feb 2023 22:27:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229506AbjBYD1Y (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 24 Feb 2023 22:27:24 -0500 Received: from mail-qt1-x82a.google.com (mail-qt1-x82a.google.com [IPv6:2607:f8b0:4864:20::82a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAE8E30E9B for <linux-kernel@vger.kernel.org>; Fri, 24 Feb 2023 19:27:22 -0800 (PST) Received: by mail-qt1-x82a.google.com with SMTP id s12so1478917qtq.11 for <linux-kernel@vger.kernel.org>; Fri, 24 Feb 2023 19:27:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=RHZn/4jVwdf9ks/OwO+bD/mVMTUWc6RD0o1MFPaoins=; b=uWe2Eq/pQEOLMRSgOscVYonTTeemsUXyln69+nf8Sz3ofpiEzS0YByxb7etlBtq48M sjCaQHukuiKkINk/J55L+okWI8+Xj0r4CvKlbWypHbaNwU8rD61e9idS1KyTtMpNWxkn bt9aL0KuJNsosHX5ft2ZfOuKTaG3O6J4aaY7Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=RHZn/4jVwdf9ks/OwO+bD/mVMTUWc6RD0o1MFPaoins=; b=Qm9txick+CMcN+IDPRIH1i57L1v2BEYOEP+yq01WpZKd4eydoRuIfZJ7uq6ZaTHpX7 //mmVVZb3cS47CgYmWpuuQ/yK3eudO/XQzZQ3YMjO3QVQ/4j8YiohBa+2N3Ltpomt3MU vSfHa5Eo3D76YOolFvaoH55J4sQNciAVs1qI/JU0kw8FzZusGi3JRrVY4QkziGRQHnaI GkjamlisMOFUzcQJI7zkY89PLXK/yWSiK/Dr2tFItxCthqTHqmgPL+vkY3Cw/0lEjx7T m8XModYoUDKc7dHvrnRwYbrRC7fRCFb0teuWQDN1opON7IsqHtVA/Tka/PAMDe7wMjP2 9i3w== X-Gm-Message-State: AO0yUKVCpaHTRY7AwyIdc6HL9vkY48tDDaWWoXtauJUQBv1fYx6EFhDL XQ6xoNO50L3xf3cKNSeS7eNNVtA62DaxBZdD X-Received: by 2002:a05:622a:5c6:b0:3b8:2602:9a35 with SMTP id d6-20020a05622a05c600b003b826029a35mr18302538qtb.52.1677295641071; Fri, 24 Feb 2023 19:27:21 -0800 (PST) Received: from joelboxx.c.googlers.com.com (129.239.188.35.bc.googleusercontent.com. [35.188.239.129]) by smtp.gmail.com with ESMTPSA id c20-20020ac853d4000000b003b62bc6cd1csm671146qtq.82.2023.02.24.19.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Feb 2023 19:27:20 -0800 (PST) From: "Joel Fernandes (Google)" <joel@joelfernandes.org> To: linux-kernel@vger.kernel.org Cc: "Joel Fernandes (Google)" <joel@joelfernandes.org>, Frederic Weisbecker <frederic@kernel.org>, Lai Jiangshan <jiangshanlai@gmail.com>, linux-doc@vger.kernel.org, "Paul E. McKenney" <paulmck@kernel.org>, rcu@vger.kernel.org Subject: [PATCH RFC] rcu: Add a minimum time for marking boot as completed Date: Sat, 25 Feb 2023 03:27:16 +0000 Message-Id: <20230225032716.3320124-1-joel@joelfernandes.org> X-Mailer: git-send-email 2.39.2.637.g21b0678d19-goog MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,URIBL_BLACK autolearn=no 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758772309368347891?= X-GMAIL-MSGID: =?utf-8?q?1758772309368347891?= |
Series |
[RFC] rcu: Add a minimum time for marking boot as completed
|
|
Commit Message
Joel Fernandes
Feb. 25, 2023, 3:27 a.m. UTC
On many systems, a great deal of boot happens after the kernel thinks the boot
has completed. It is difficult to determine if the system has really booted
from the kernel side. Some features like lazy-RCU can risk slowing down boot
time if, say, a callback has been added that the boot synchronously depends on.
Further, it is better to boot systems which pass 'rcu_normal_after_boot' to
stay expedited for as long as the system is still booting.
For these reasons, this commit adds a config option
'CONFIG_RCU_BOOT_END_DELAY' and a boot parameter rcupdate.boot_end_delay.
By default, this value is 20s. A system designer can choose to specify a value
here to keep RCU from marking boot completion. The boot sequence will not be
marked ended until at least boot_end_delay milliseconds have passed.
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
---
.../admin-guide/kernel-parameters.txt | 4 +++
kernel/rcu/Kconfig | 12 +++++++++
kernel/rcu/update.c | 25 +++++++++++++++++--
3 files changed, 39 insertions(+), 2 deletions(-)
Comments
Hi-- On 2/24/23 19:27, Joel Fernandes (Google) wrote: > On many systems, a great deal of boot happens after the kernel thinks the boot > has completed. It is difficult to determine if the system has really booted > from the kernel side. Some features like lazy-RCU can risk slowing down boot > time if, say, a callback has been added that the boot synchronously depends on. > > Further, it is better to boot systems which pass 'rcu_normal_after_boot' to > stay expedited for as long as the system is still booting. > > For these reasons, this commit adds a config option > 'CONFIG_RCU_BOOT_END_DELAY' and a boot parameter rcupdate.boot_end_delay. > > By default, this value is 20s. A system designer can choose to specify a value > here to keep RCU from marking boot completion. The boot sequence will not be > marked ended until at least boot_end_delay milliseconds have passed. > > Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org> > --- > .../admin-guide/kernel-parameters.txt | 4 +++ > kernel/rcu/Kconfig | 12 +++++++++ > kernel/rcu/update.c | 25 +++++++++++++++++-- > 3 files changed, 39 insertions(+), 2 deletions(-) > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index 2429b5e3184b..0943139fdf01 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -5085,6 +5085,10 @@ > rcutorture.verbose= [KNL] > Enable additional printk() statements. > > + rcupdate.boot_end_delay= [KNL] Tell units: > + Minimum time that must elapse before the boot + Minimum time in milliseconds that must elapse before the boot > + sequence can be marked as completed. > + > rcupdate.rcu_cpu_stall_ftrace_dump= [KNL] > Dump ftrace buffer after reporting RCU CPU > stall warning. > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig > index 9071182b1284..1033a38bddad 100644 > --- a/kernel/rcu/Kconfig > +++ b/kernel/rcu/Kconfig > @@ -217,6 +217,18 @@ config RCU_BOOST_DELAY > > Accept the default if unsure. > > +config RCU_BOOT_END_DELAY > + int "Minimum delay before RCU considers boot has completed" > + range 0 120000 > + default 20000 > + help > + This option specifies the minmum time since boot before which tpyo: minimum > + RCU believes the system is booted. The actual delay can be > + higher than this if the kernel takes a long time to initialize > + but it will never be smaller than this. + Specified in milliseconds. > + > + Accept the default if unsure. > + > config RCU_EXP_KTHREAD > bool "Perform RCU expedited work in a real-time kthread" > depends on RCU_BOOST && RCU_EXPERT > diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c > index 19bf6fa3ee6a..5b73341d9b89 100644 > --- a/kernel/rcu/update.c > +++ b/kernel/rcu/update.c > @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); > #endif > #endif /* #ifndef CONFIG_TINY_RCU */ > > +/* Minimum time until RCU considers boot as completed. */ > +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; > +module_param(boot_end_delay, int, 0444); > + > #ifdef CONFIG_DEBUG_LOCK_ALLOC > /** > * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? > @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) > EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); > > static bool rcu_boot_ended __read_mostly; > - > /* > - * Inform RCU of the end of the in-kernel boot sequence. > + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will > + * not be marked ended until at least boot_end_delay milliseconds have passed. > */ > +void rcu_end_inkernel_boot(void); > +static void boot_rcu_work_fn(struct work_struct *work) > +{ > + rcu_end_inkernel_boot(); > +} > +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); > + > void rcu_end_inkernel_boot(void) > { > + if (boot_end_delay) { > + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; Is that division OK on 32-bit? Might have to use a helper macro. (I dunno.) > + > + if (boot_ms < boot_end_delay) { > + schedule_delayed_work(&boot_rcu_work, > + boot_end_delay - boot_ms); > + return; > + } > + } > + > rcu_unexpedite_gp(); > rcu_async_relax(); > if (rcu_normal_after_boot)
On Fri, Feb 24, 2023 at 07:32:22PM -0800, Randy Dunlap wrote: > Hi-- > > On 2/24/23 19:27, Joel Fernandes (Google) wrote: > > On many systems, a great deal of boot happens after the kernel thinks the boot > > has completed. It is difficult to determine if the system has really booted > > from the kernel side. Some features like lazy-RCU can risk slowing down boot > > time if, say, a callback has been added that the boot synchronously depends on. > > > > Further, it is better to boot systems which pass 'rcu_normal_after_boot' to > > stay expedited for as long as the system is still booting. > > > > For these reasons, this commit adds a config option > > 'CONFIG_RCU_BOOT_END_DELAY' and a boot parameter rcupdate.boot_end_delay. > > > > By default, this value is 20s. A system designer can choose to specify a value > > here to keep RCU from marking boot completion. The boot sequence will not be > > marked ended until at least boot_end_delay milliseconds have passed. > > > > Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org> > > --- > > .../admin-guide/kernel-parameters.txt | 4 +++ > > kernel/rcu/Kconfig | 12 +++++++++ > > kernel/rcu/update.c | 25 +++++++++++++++++-- > > 3 files changed, 39 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > > index 2429b5e3184b..0943139fdf01 100644 > > --- a/Documentation/admin-guide/kernel-parameters.txt > > +++ b/Documentation/admin-guide/kernel-parameters.txt > > @@ -5085,6 +5085,10 @@ > > rcutorture.verbose= [KNL] > > Enable additional printk() statements. > > > > + rcupdate.boot_end_delay= [KNL] > > Tell units: > > > + Minimum time that must elapse before the boot > Fixed. > + Minimum time in milliseconds that must elapse before the boot > > > + sequence can be marked as completed. > > + > > rcupdate.rcu_cpu_stall_ftrace_dump= [KNL] > > Dump ftrace buffer after reporting RCU CPU > > stall warning. > > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig > > index 9071182b1284..1033a38bddad 100644 > > --- a/kernel/rcu/Kconfig > > +++ b/kernel/rcu/Kconfig > > @@ -217,6 +217,18 @@ config RCU_BOOST_DELAY > > > > Accept the default if unsure. > > > > +config RCU_BOOT_END_DELAY > > + int "Minimum delay before RCU considers boot has completed" > > + range 0 120000 > > + default 20000 > > + help > > + This option specifies the minmum time since boot before which > > tpyo: minimum > > > + RCU believes the system is booted. The actual delay can be > > + higher than this if the kernel takes a long time to initialize > > + but it will never be smaller than this. Fixed. > + Specified in milliseconds. > > > + > > + Accept the default if unsure. > > + > > config RCU_EXP_KTHREAD > > bool "Perform RCU expedited work in a real-time kthread" > > depends on RCU_BOOST && RCU_EXPERT > > diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c > > index 19bf6fa3ee6a..5b73341d9b89 100644 > > --- a/kernel/rcu/update.c > > +++ b/kernel/rcu/update.c > > @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); > > #endif > > #endif /* #ifndef CONFIG_TINY_RCU */ > > > > +/* Minimum time until RCU considers boot as completed. */ > > +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; > > +module_param(boot_end_delay, int, 0444); > > + > > #ifdef CONFIG_DEBUG_LOCK_ALLOC > > /** > > * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? > > @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) > > EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); > > > > static bool rcu_boot_ended __read_mostly; > > - > > /* > > - * Inform RCU of the end of the in-kernel boot sequence. > > + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will > > + * not be marked ended until at least boot_end_delay milliseconds have passed. > > */ > > +void rcu_end_inkernel_boot(void); > > +static void boot_rcu_work_fn(struct work_struct *work) > > +{ > > + rcu_end_inkernel_boot(); > > +} > > +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); > > + > > void rcu_end_inkernel_boot(void) > > { > > + if (boot_end_delay) { > > + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; > > Is that division OK on 32-bit? Might have to use a helper macro. (I dunno.) Ah, maybe. I am not sure if the compiler generates the right stubs. At least in userspace it does and there's no problem on 32-bit system. I will research it more, perhaps by building a 32-bit kernel and seeing what the compiler does. Will re-spin later after any more feedback. thanks, - Joel > > > + > > + if (boot_ms < boot_end_delay) { > > + schedule_delayed_work(&boot_rcu_work, > > + boot_end_delay - boot_ms); > > + return; > > + } > > + } > > + > > rcu_unexpedite_gp(); > > rcu_async_relax(); > > if (rcu_normal_after_boot) > > -- > ~Randy
On Fri, Feb 24, 2023 at 07:32:22PM -0800, Randy Dunlap wrote: [..] > > + > > + Accept the default if unsure. > > + > > config RCU_EXP_KTHREAD > > bool "Perform RCU expedited work in a real-time kthread" > > depends on RCU_BOOST && RCU_EXPERT > > diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c > > index 19bf6fa3ee6a..5b73341d9b89 100644 > > --- a/kernel/rcu/update.c > > +++ b/kernel/rcu/update.c > > @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); > > #endif > > #endif /* #ifndef CONFIG_TINY_RCU */ > > > > +/* Minimum time until RCU considers boot as completed. */ > > +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; > > +module_param(boot_end_delay, int, 0444); > > + > > #ifdef CONFIG_DEBUG_LOCK_ALLOC > > /** > > * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? > > @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) > > EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); > > > > static bool rcu_boot_ended __read_mostly; > > - > > /* > > - * Inform RCU of the end of the in-kernel boot sequence. > > + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will > > + * not be marked ended until at least boot_end_delay milliseconds have passed. > > */ > > +void rcu_end_inkernel_boot(void); > > +static void boot_rcu_work_fn(struct work_struct *work) > > +{ > > + rcu_end_inkernel_boot(); > > +} > > +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); > > + > > void rcu_end_inkernel_boot(void) > > { > > + if (boot_end_delay) { > > + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; > > Is that division OK on 32-bit? Might have to use a helper macro. (I dunno.) I believe the below should work on 32-bit, but I will test it more. It does on 64-bit. Thanks! ---8<----------------------- diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index cbdad7b46841..2f539c18b310 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -243,7 +243,7 @@ static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); void rcu_end_inkernel_boot(void) { if (boot_end_delay) { - u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; + u64 boot_ms = div_u64(ktime_get_boot_fast_ns(), 1000000UL); if (boot_ms < boot_end_delay) { schedule_delayed_work(&boot_rcu_work,
On 2/24/23 19:59, Joel Fernandes wrote: > On Fri, Feb 24, 2023 at 07:32:22PM -0800, Randy Dunlap wrote: > [..] >>> + >>> + Accept the default if unsure. >>> + >>> config RCU_EXP_KTHREAD >>> bool "Perform RCU expedited work in a real-time kthread" >>> depends on RCU_BOOST && RCU_EXPERT >>> diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c >>> index 19bf6fa3ee6a..5b73341d9b89 100644 >>> --- a/kernel/rcu/update.c >>> +++ b/kernel/rcu/update.c >>> @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); >>> #endif >>> #endif /* #ifndef CONFIG_TINY_RCU */ >>> >>> +/* Minimum time until RCU considers boot as completed. */ >>> +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; >>> +module_param(boot_end_delay, int, 0444); >>> + >>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>> /** >>> * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? >>> @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) >>> EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); >>> >>> static bool rcu_boot_ended __read_mostly; >>> - >>> /* >>> - * Inform RCU of the end of the in-kernel boot sequence. >>> + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will >>> + * not be marked ended until at least boot_end_delay milliseconds have passed. >>> */ >>> +void rcu_end_inkernel_boot(void); >>> +static void boot_rcu_work_fn(struct work_struct *work) >>> +{ >>> + rcu_end_inkernel_boot(); >>> +} >>> +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); >>> + >>> void rcu_end_inkernel_boot(void) >>> { >>> + if (boot_end_delay) { >>> + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; >> >> Is that division OK on 32-bit? Might have to use a helper macro. (I dunno.) > > I believe the below should work on 32-bit, but I will test it more. It does > on 64-bit. > > Thanks! > > ---8<----------------------- > > diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c > index cbdad7b46841..2f539c18b310 100644 > --- a/kernel/rcu/update.c > +++ b/kernel/rcu/update.c > @@ -243,7 +243,7 @@ static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); > void rcu_end_inkernel_boot(void) > { > if (boot_end_delay) { > - u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; > + u64 boot_ms = div_u64(ktime_get_boot_fast_ns(), 1000000UL); > > if (boot_ms < boot_end_delay) { > schedule_delayed_work(&boot_rcu_work, Joel, this now builds cleanly on 32-bit. Before the patch: ld: kernel/rcu/update.o: in function `boot_rcu_work_fn': update.c:(.text+0x4623): undefined reference to `__udivdi3' ld: kernel/rcu/update.o: in function `rcu_end_inkernel_boot': update.c:(.text+0x46b3): undefined reference to `__udivdi3' I don't know what the second one refers to, but it didn't show up after the patch above (using div_u64()). Thanks.
> On Feb 26, 2023, at 7:03 PM, Randy Dunlap <rdunlap@infradead.org> wrote: > > > >> On 2/24/23 19:59, Joel Fernandes wrote: >> On Fri, Feb 24, 2023 at 07:32:22PM -0800, Randy Dunlap wrote: >> [..] >>>> + >>>> + Accept the default if unsure. >>>> + >>>> config RCU_EXP_KTHREAD >>>> bool "Perform RCU expedited work in a real-time kthread" >>>> depends on RCU_BOOST && RCU_EXPERT >>>> diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c >>>> index 19bf6fa3ee6a..5b73341d9b89 100644 >>>> --- a/kernel/rcu/update.c >>>> +++ b/kernel/rcu/update.c >>>> @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); >>>> #endif >>>> #endif /* #ifndef CONFIG_TINY_RCU */ >>>> >>>> +/* Minimum time until RCU considers boot as completed. */ >>>> +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; >>>> +module_param(boot_end_delay, int, 0444); >>>> + >>>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>>> /** >>>> * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? >>>> @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) >>>> EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); >>>> >>>> static bool rcu_boot_ended __read_mostly; >>>> - >>>> /* >>>> - * Inform RCU of the end of the in-kernel boot sequence. >>>> + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will >>>> + * not be marked ended until at least boot_end_delay milliseconds have passed. >>>> */ >>>> +void rcu_end_inkernel_boot(void); >>>> +static void boot_rcu_work_fn(struct work_struct *work) >>>> +{ >>>> + rcu_end_inkernel_boot(); >>>> +} >>>> +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); >>>> + >>>> void rcu_end_inkernel_boot(void) >>>> { >>>> + if (boot_end_delay) { >>>> + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; >>> >>> Is that division OK on 32-bit? Might have to use a helper macro. (I dunno.) >> >> I believe the below should work on 32-bit, but I will test it more. It does >> on 64-bit. >> >> Thanks! >> >> ---8<----------------------- >> >> diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c >> index cbdad7b46841..2f539c18b310 100644 >> --- a/kernel/rcu/update.c >> +++ b/kernel/rcu/update.c >> @@ -243,7 +243,7 @@ static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); >> void rcu_end_inkernel_boot(void) >> { >> if (boot_end_delay) { >> - u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; >> + u64 boot_ms = div_u64(ktime_get_boot_fast_ns(), 1000000UL); >> >> if (boot_ms < boot_end_delay) { >> schedule_delayed_work(&boot_rcu_work, > > Joel, this now builds cleanly on 32-bit. Before the patch: > > ld: kernel/rcu/update.o: in function `boot_rcu_work_fn': > update.c:(.text+0x4623): undefined reference to `__udivdi3' > ld: kernel/rcu/update.o: in function `rcu_end_inkernel_boot': > update.c:(.text+0x46b3): undefined reference to `__udivdi3' > > I don't know what the second one refers to, but it didn't show up > after the patch above (using div_u64()). Thanks a lot, I will update the patch with this in the next spin. - Joel > > Thanks. > -- > ~Randy
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 2429b5e3184b..0943139fdf01 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5085,6 +5085,10 @@ rcutorture.verbose= [KNL] Enable additional printk() statements. + rcupdate.boot_end_delay= [KNL] + Minimum time that must elapse before the boot + sequence can be marked as completed. + rcupdate.rcu_cpu_stall_ftrace_dump= [KNL] Dump ftrace buffer after reporting RCU CPU stall warning. diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index 9071182b1284..1033a38bddad 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -217,6 +217,18 @@ config RCU_BOOST_DELAY Accept the default if unsure. +config RCU_BOOT_END_DELAY + int "Minimum delay before RCU considers boot has completed" + range 0 120000 + default 20000 + help + This option specifies the minmum time since boot before which + RCU believes the system is booted. The actual delay can be + higher than this if the kernel takes a long time to initialize + but it will never be smaller than this. + + Accept the default if unsure. + config RCU_EXP_KTHREAD bool "Perform RCU expedited work in a real-time kthread" depends on RCU_BOOST && RCU_EXPERT diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index 19bf6fa3ee6a..5b73341d9b89 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -62,6 +62,10 @@ module_param(rcu_normal_after_boot, int, 0444); #endif #endif /* #ifndef CONFIG_TINY_RCU */ +/* Minimum time until RCU considers boot as completed. */ +static int boot_end_delay = CONFIG_RCU_BOOT_END_DELAY; +module_param(boot_end_delay, int, 0444); + #ifdef CONFIG_DEBUG_LOCK_ALLOC /** * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section? @@ -225,12 +229,29 @@ void rcu_unexpedite_gp(void) EXPORT_SYMBOL_GPL(rcu_unexpedite_gp); static bool rcu_boot_ended __read_mostly; - /* - * Inform RCU of the end of the in-kernel boot sequence. + * Inform RCU of the end of the in-kernel boot sequence. The boot sequence will + * not be marked ended until at least boot_end_delay milliseconds have passed. */ +void rcu_end_inkernel_boot(void); +static void boot_rcu_work_fn(struct work_struct *work) +{ + rcu_end_inkernel_boot(); +} +static DECLARE_DELAYED_WORK(boot_rcu_work, boot_rcu_work_fn); + void rcu_end_inkernel_boot(void) { + if (boot_end_delay) { + u64 boot_ms = ktime_get_boot_fast_ns() / 1000000UL; + + if (boot_ms < boot_end_delay) { + schedule_delayed_work(&boot_rcu_work, + boot_end_delay - boot_ms); + return; + } + } + rcu_unexpedite_gp(); rcu_async_relax(); if (rcu_normal_after_boot)