Message ID | 20221215035755.2820163-1-qiang1.zhang@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp124782wrn; Wed, 14 Dec 2022 19:55:24 -0800 (PST) X-Google-Smtp-Source: AA0mqf7s+g3LXT2liNXncj+iiaPjBXTQZzXjvabUuUrZVyXpaNQJN63jwdsSiRpVvjac1SFH8XPn X-Received: by 2002:a05:6a20:8f04:b0:a4:aa40:2260 with SMTP id b4-20020a056a208f0400b000a4aa402260mr52230337pzk.60.1671076523727; Wed, 14 Dec 2022 19:55:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671076523; cv=none; d=google.com; s=arc-20160816; b=G4p5y5h4NTddWkjldpOahd9mZ7hz/IfZZjwnY5apVsCyvlmRUzZs+ZU7IOYBq/SYWm sEHy4fXPMk/i3aAHJOpTQ4eBnBG7YScUpwrx66hd13uxwI7uah285es9RZ1DOfv8FW2A MBFR06S12BjCug+HjjjfQEZu2qyvfKSwF02UhElbw9E2KpiFBzkDnFyoTN0McgnMPqtz s06yUyFAmXPiLjSThsRmHpt6jFeTdieyqyMOLpPZmt3kE7QPzDv62zRzs+JtQsNi1yff IuyyyPgCiNkrCn9S6WgvaJl8CNZt70n4xN6eLMCsXjqNBmNryaADVhuNHIQ35kr4aj1m MNIA== 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=w9/dNUQQAad0ycCHLHpe+drHczsLoQcuYmyjMl/Pm0w=; b=TXsGH/Nl+dkI3ZB2toUKqlyhft4Q+9IVdivH0gw/EmmLXyMXfBY+geRWGA6lcBSDrk IrYiM3Qs+tZJw+nz1AXwZ0ifHYj22M4UnxF3U5bhBahCc1FeZFMIk7ri1HvoRwcUZLmA SM/5oE6dpRM7/1YankSZaAU4NTJwbva3SNvrthuuKgGpqfZ3HjhhAyxLGXOB62TjJ+yS rBODKyDQxrDmNNB4DlK6Zm9IInPLHo12EPrtZTOAAIK1qL7xTRiVO4qw9+bIzrtFLphP s2gvPp/bth8FOkHRSRMmnQcdAYoCr8rOMyFDmGTReM16ItFpjqve5dHXhUTkfjtTp39l gYuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=LVWjSKuZ; 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=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g129-20020a636b87000000b00482b5444680si262003pgc.278.2022.12.14.19.55.09; Wed, 14 Dec 2022 19:55:23 -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=@intel.com header.s=Intel header.b=LVWjSKuZ; 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=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229614AbiLODwm (ORCPT <rfc822;jeantsuru.cumc.mandola@gmail.com> + 99 others); Wed, 14 Dec 2022 22:52:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229632AbiLODw3 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 14 Dec 2022 22:52:29 -0500 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E36D355A9A; Wed, 14 Dec 2022 19:52:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1671076348; x=1702612348; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=Jj0nRxwLU+V9DN32BOIUegCyAzKtt5gtTufXftUHSM0=; b=LVWjSKuZ8h0878O05tqQD4XdHPiISEquswn0Jmek2aezpUG6FjHTGPWA luAct5T3ckBr/Wbvxn3a0JveF1NNcJu1DjsCZzr4SQ9m+c+vh1kh1VK62 +SEdOMTxVgEOKmKcUzpZkgFrBiW6Y0nXz/ZiB3ygR0rRloXB74ANSdDot M7e399Abykl8w6kCGYbd3gnI57Tc7OIe2ycYlgagM3YOWkyd3/M/S11TT W+WnC/olHiJS/rSNaxk77NhsN/3WEJ4iArorL90sZSyxDcl90YmEdb3cc nVvbqNEXU0hnyjTQz14ECEetMfDh2kE4QgFXF8ihYEhgKj2dF7aGTH9ON A==; X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="298922376" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="298922376" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 19:52:20 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="773564476" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="773564476" Received: from zq-optiplex-7090.bj.intel.com ([10.238.156.129]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 19:52:17 -0800 From: Zqiang <qiang1.zhang@intel.com> To: paulmck@kernel.org, frederic@kernel.org, quic_neeraju@quicinc.com, joel@joelfernandes.org Cc: rcu@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] rcu: Fix opposite might_sleep() check in rcu_blocking_is_gp() Date: Thu, 15 Dec 2022 11:57:55 +0800 Message-Id: <20221215035755.2820163-1-qiang1.zhang@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE 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: <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?1752250737222918469?= X-GMAIL-MSGID: =?utf-8?q?1752250737222918469?= |
Series |
rcu: Fix opposite might_sleep() check in rcu_blocking_is_gp()
|
|
Commit Message
Zqiang
Dec. 15, 2022, 3:57 a.m. UTC
Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke
synchronize_rcu_*() will implies a grace period and return directly,
so there is no sleep action due to waiting for a grace period to end,
but this might_sleep() check is the opposite. therefore, this commit
puts might_sleep() check in the correct palce.
Signed-off-by: Zqiang <qiang1.zhang@intel.com>
---
kernel/rcu/tree.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Comments
On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > synchronize_rcu_*() will implies a grace period and return directly, > so there is no sleep action due to waiting for a grace period to end, > but this might_sleep() check is the opposite. therefore, this commit > puts might_sleep() check in the correct palce. > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> Queued for testing and review, thank you! I was under the impression that might_sleep() did some lockdep-based checking, but I am unable to find it. If there really is such checking, that would be a potential argument for leaving this code as it is. But in the meantime, full speed ahead! ;-) Thanx, Paul > --- > kernel/rcu/tree.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index ee8a6a711719..65f3dd2fd3ae 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -3379,9 +3379,10 @@ void __init kfree_rcu_scheduler_running(void) > */ > static int rcu_blocking_is_gp(void) > { > - if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) > + if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) { > + might_sleep(); > return false; > - might_sleep(); /* Check for RCU read-side critical section. */ > + } > return true; > } > > -- > 2.25.1 >
On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > synchronize_rcu_*() will implies a grace period and return directly, > so there is no sleep action due to waiting for a grace period to end, > but this might_sleep() check is the opposite. therefore, this commit > puts might_sleep() check in the correct palce. > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > >Queued for testing and review, thank you! > >I was under the impression that might_sleep() did some lockdep-based >checking, but I am unable to find it. If there really is such checking, >that would be a potential argument for leaving this code as it is. > __might_sleep __might_resched(file, line, 0) rcu_sleep_check() Does it refer to this rcu_sleep_check() ? If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. Thanks Zqiang >But in the meantime, full speed ahead! ;-) > > Thanx, Paul > > --- > kernel/rcu/tree.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index ee8a6a711719..65f3dd2fd3ae 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -3379,9 +3379,10 @@ void __init kfree_rcu_scheduler_running(void) > */ > static int rcu_blocking_is_gp(void) > { > - if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) > + if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) { > + might_sleep(); > return false; > - might_sleep(); /* Check for RCU read-side critical section. */ > + } > return true; > } > > -- > 2.25.1 >
On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > synchronize_rcu_*() will implies a grace period and return directly, > so there is no sleep action due to waiting for a grace period to end, > but this might_sleep() check is the opposite. therefore, this commit > puts might_sleep() check in the correct palce. > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > >Queued for testing and review, thank you! > >I was under the impression that might_sleep() did some lockdep-based >checking, but I am unable to find it. If there really is such checking, >that would be a potential argument for leaving this code as it is. > > >__might_sleep > __might_resched(file, line, 0) > rcu_sleep_check() > >Does it refer to this rcu_sleep_check() ? > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. Thanks Zqiang >Thanks >Zqiang > >But in the meantime, full speed ahead! ;-) > > Thanx, Paul > > --- > kernel/rcu/tree.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index ee8a6a711719..65f3dd2fd3ae 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -3379,9 +3379,10 @@ void __init kfree_rcu_scheduler_running(void) > */ > static int rcu_blocking_is_gp(void) > { > - if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) > + if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) { > + might_sleep(); > return false; > - might_sleep(); /* Check for RCU read-side critical section. */ > + } > return true; > } > > -- > 2.25.1 >
On Sat, Dec 17, 2022 at 02:44:47AM +0000, Zhang, Qiang1 wrote: > > On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > > synchronize_rcu_*() will implies a grace period and return directly, > > so there is no sleep action due to waiting for a grace period to end, > > but this might_sleep() check is the opposite. therefore, this commit > > puts might_sleep() check in the correct palce. > > > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > > > >Queued for testing and review, thank you! > > > >I was under the impression that might_sleep() did some lockdep-based > >checking, but I am unable to find it. If there really is such checking, > >that would be a potential argument for leaving this code as it is. > > > > > >__might_sleep > > __might_resched(file, line, 0) > > rcu_sleep_check() > > > >Does it refer to this rcu_sleep_check() ? > > > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always > >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. Very good, thank you! Thoughts from others? Thanx, Paul > Thanks > Zqiang > > >Thanks > >Zqiang > > > > >But in the meantime, full speed ahead! ;-) > > > > Thanx, Paul > > > > --- > > kernel/rcu/tree.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > index ee8a6a711719..65f3dd2fd3ae 100644 > > --- a/kernel/rcu/tree.c > > +++ b/kernel/rcu/tree.c > > @@ -3379,9 +3379,10 @@ void __init kfree_rcu_scheduler_running(void) > > */ > > static int rcu_blocking_is_gp(void) > > { > > - if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) > > + if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) { > > + might_sleep(); > > return false; > > - might_sleep(); /* Check for RCU read-side critical section. */ > > + } > > return true; > > } > > > > -- > > 2.25.1 > >
On Fri, Dec 16, 2022 at 09:17:59PM -0800, Paul E. McKenney wrote: > On Sat, Dec 17, 2022 at 02:44:47AM +0000, Zhang, Qiang1 wrote: > > > > On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > > > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > > > synchronize_rcu_*() will implies a grace period and return directly, > > > so there is no sleep action due to waiting for a grace period to end, > > > but this might_sleep() check is the opposite. therefore, this commit > > > puts might_sleep() check in the correct palce. > > > > > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > > > > > >Queued for testing and review, thank you! > > > > > >I was under the impression that might_sleep() did some lockdep-based > > >checking, but I am unable to find it. If there really is such checking, > > >that would be a potential argument for leaving this code as it is. > > > > > > > > >__might_sleep > > > __might_resched(file, line, 0) > > > rcu_sleep_check() > > > > > >Does it refer to this rcu_sleep_check() ? > > > > > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always > > >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > > > > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. > > Very good, thank you! > > Thoughts from others? Please consider this as a best-effort comment that might be missing details: The might_sleep() was added in 18fec7d8758d ("rcu: Improve synchronize_rcu() diagnostics") Since it is illegal to call a blocking API like synchronize_rcu() in a non-preemptible section, is there any harm in just calling might_sleep() uncomditionally in rcu_block_is_gp() ? I think it is a bit irrelevant if synchronize_rcu() is called from a call path, before scheduler is initialized, or after. The fact that it was even called from a non-preemptible section is a red-flag, considering if such non-preemptible section may call synchronize_rcu() API in the future, after full boot up, even if rarely. For this reason, IMHO there is still value in doing the might_sleep() check unconditionally. Say if a common code path is invoked both before RCU_SCHEDULER_INIT and *very rarely* after RCU_SCHEDULER_INIT. Or is there more of a point in doing this check if scheduler is initialized from RCU perspective ? If not, I would do something like this: ---8<----------------------- diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 79aea7df4345..23c2303de9f4 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) { int ret; + might_sleep(); /* Check for RCU read-side critical section. */ + // Invoking preempt_model_*() too early gets a splat. if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || preempt_model_full() || preempt_model_rt()) return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; - might_sleep(); /* Check for RCU read-side critical section. */ preempt_disable(); /* * If the rcu_state.n_online_cpus counter is equal to one,
On Sun, Dec 18, 2022 at 02:01:11AM +0000, Joel Fernandes wrote: > On Fri, Dec 16, 2022 at 09:17:59PM -0800, Paul E. McKenney wrote: > > On Sat, Dec 17, 2022 at 02:44:47AM +0000, Zhang, Qiang1 wrote: > > > > > > On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > > > > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > > > > synchronize_rcu_*() will implies a grace period and return directly, > > > > so there is no sleep action due to waiting for a grace period to end, > > > > but this might_sleep() check is the opposite. therefore, this commit > > > > puts might_sleep() check in the correct palce. > > > > > > > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > > > > > > > >Queued for testing and review, thank you! > > > > > > > >I was under the impression that might_sleep() did some lockdep-based > > > >checking, but I am unable to find it. If there really is such checking, > > > >that would be a potential argument for leaving this code as it is. > > > > > > > > > > > >__might_sleep > > > > __might_resched(file, line, 0) > > > > rcu_sleep_check() > > > > > > > >Does it refer to this rcu_sleep_check() ? > > > > > > > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always > > > >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > > > > > > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. > > > > Very good, thank you! > > > > Thoughts from others? > > Please consider this as a best-effort comment that might be missing details: > > The might_sleep() was added in 18fec7d8758d ("rcu: Improve synchronize_rcu() > diagnostics") > > Since it is illegal to call a blocking API like synchronize_rcu() in a > non-preemptible section, is there any harm in just calling might_sleep() > uncomditionally in rcu_block_is_gp() ? I think it is a bit irrelevant if > synchronize_rcu() is called from a call path, before scheduler is > initialized, or after. The fact that it was even called from a > non-preemptible section is a red-flag, considering if such non-preemptible > section may call synchronize_rcu() API in the future, after full boot up, > even if rarely. > > For this reason, IMHO there is still value in doing the might_sleep() check > unconditionally. Say if a common code path is invoked both before > RCU_SCHEDULER_INIT and *very rarely* after RCU_SCHEDULER_INIT. > > Or is there more of a point in doing this check if scheduler is initialized > from RCU perspective ? One advantage of its current placement would be if might_sleep() ever unconditionally checks for interrupts being disabled. I don't believe that might_sleep() will do that any time soon given the likely fallout from code invoked at early boot as well as from runtime, but why be in the way of that additional diagnostic check? Thanx, Paul > If not, I would do something like this: > > ---8<----------------------- > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index 79aea7df4345..23c2303de9f4 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) > { > int ret; > > + might_sleep(); /* Check for RCU read-side critical section. */ > + > // Invoking preempt_model_*() too early gets a splat. > if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || > preempt_model_full() || preempt_model_rt()) > return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; > - might_sleep(); /* Check for RCU read-side critical section. */ > preempt_disable(); > /* > * If the rcu_state.n_online_cpus counter is equal to one,
On Sun, Dec 18, 2022 at 1:06 PM Paul E. McKenney <paulmck@kernel.org> wrote: > > On Sun, Dec 18, 2022 at 02:01:11AM +0000, Joel Fernandes wrote: > > On Fri, Dec 16, 2022 at 09:17:59PM -0800, Paul E. McKenney wrote: > > > On Sat, Dec 17, 2022 at 02:44:47AM +0000, Zhang, Qiang1 wrote: > > > > > > > > On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > > > > > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > > > > > synchronize_rcu_*() will implies a grace period and return directly, > > > > > so there is no sleep action due to waiting for a grace period to end, > > > > > but this might_sleep() check is the opposite. therefore, this commit > > > > > puts might_sleep() check in the correct palce. > > > > > > > > > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > > > > > > > > > >Queued for testing and review, thank you! > > > > > > > > > >I was under the impression that might_sleep() did some lockdep-based > > > > >checking, but I am unable to find it. If there really is such checking, > > > > >that would be a potential argument for leaving this code as it is. > > > > > > > > > > > > > > >__might_sleep > > > > > __might_resched(file, line, 0) > > > > > rcu_sleep_check() > > > > > > > > > >Does it refer to this rcu_sleep_check() ? > > > > > > > > > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always > > > > >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > > > > > > > > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. > > > > > > Very good, thank you! > > > > > > Thoughts from others? > > > > Please consider this as a best-effort comment that might be missing details: > > > > The might_sleep() was added in 18fec7d8758d ("rcu: Improve synchronize_rcu() > > diagnostics") > > > > Since it is illegal to call a blocking API like synchronize_rcu() in a > > non-preemptible section, is there any harm in just calling might_sleep() > > uncomditionally in rcu_block_is_gp() ? I think it is a bit irrelevant if > > synchronize_rcu() is called from a call path, before scheduler is > > initialized, or after. The fact that it was even called from a > > non-preemptible section is a red-flag, considering if such non-preemptible > > section may call synchronize_rcu() API in the future, after full boot up, > > even if rarely. > > > > For this reason, IMHO there is still value in doing the might_sleep() check > > unconditionally. Say if a common code path is invoked both before > > RCU_SCHEDULER_INIT and *very rarely* after RCU_SCHEDULER_INIT. > > > > Or is there more of a point in doing this check if scheduler is initialized > > from RCU perspective ? > > One advantage of its current placement would be if might_sleep() ever > unconditionally checks for interrupts being disabled. > > I don't believe that might_sleep() will do that any time soon given the > likely fallout from code invoked at early boot as well as from runtime, > but why be in the way of that additional diagnostic check? If I understand the current code, might_sleep() is invoked only if the scheduler is INACTIVE from RCU perspective, and I don't think here are reports of fall out. That is current code behavior. Situation right now is: might_sleep() only if the state is INACTIVE. Qiang's patch: might_sleep() only if the state is NOT INACTIVE. My suggestion: might_sleep() regardless of the state. Is there a reason my suggestion will not work? Apologies if I misunderstood something. thanks, - Joel > > Thanx, Paul > > > If not, I would do something like this: > > > > ---8<----------------------- > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > index 79aea7df4345..23c2303de9f4 100644 > > --- a/kernel/rcu/tree.c > > +++ b/kernel/rcu/tree.c > > @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) > > { > > int ret; > > > > + might_sleep(); /* Check for RCU read-side critical section. */ > > + > > // Invoking preempt_model_*() too early gets a splat. > > if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || > > preempt_model_full() || preempt_model_rt()) > > return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; > > - might_sleep(); /* Check for RCU read-side critical section. */ > > preempt_disable(); > > /* > > * If the rcu_state.n_online_cpus counter is equal to one,
On Sun, Dec 18, 2022 at 02:29:10PM -0500, Joel Fernandes wrote: > On Sun, Dec 18, 2022 at 1:06 PM Paul E. McKenney <paulmck@kernel.org> wrote: > > > > On Sun, Dec 18, 2022 at 02:01:11AM +0000, Joel Fernandes wrote: > > > On Fri, Dec 16, 2022 at 09:17:59PM -0800, Paul E. McKenney wrote: > > > > On Sat, Dec 17, 2022 at 02:44:47AM +0000, Zhang, Qiang1 wrote: > > > > > > > > > > On Thu, Dec 15, 2022 at 11:57:55AM +0800, Zqiang wrote: > > > > > > Currently, if the system is in the RCU_SCHEDULER_INACTIVE state, invoke > > > > > > synchronize_rcu_*() will implies a grace period and return directly, > > > > > > so there is no sleep action due to waiting for a grace period to end, > > > > > > but this might_sleep() check is the opposite. therefore, this commit > > > > > > puts might_sleep() check in the correct palce. > > > > > > > > > > > > Signed-off-by: Zqiang <qiang1.zhang@intel.com> > > > > > > > > > > > >Queued for testing and review, thank you! > > > > > > > > > > > >I was under the impression that might_sleep() did some lockdep-based > > > > > >checking, but I am unable to find it. If there really is such checking, > > > > > >that would be a potential argument for leaving this code as it is. > > > > > > > > > > > > > > > > > >__might_sleep > > > > > > __might_resched(file, line, 0) > > > > > > rcu_sleep_check() > > > > > > > > > > > >Does it refer to this rcu_sleep_check() ? > > > > > > > > > > > >If so, when in the RCU_SCHEDULER_INACTIVE state, the debug_lockdep_rcu_enabled() is always > > > > > >return false, so the RCU_LOCKDEP_WARN() also does not produce an actual warning. > > > > > > > > > > and when the system_state == SYSTEM_BOOTING, we just did rcu_sleep_check() and then return. > > > > > > > > Very good, thank you! > > > > > > > > Thoughts from others? > > > > > > Please consider this as a best-effort comment that might be missing details: > > > > > > The might_sleep() was added in 18fec7d8758d ("rcu: Improve synchronize_rcu() > > > diagnostics") > > > > > > Since it is illegal to call a blocking API like synchronize_rcu() in a > > > non-preemptible section, is there any harm in just calling might_sleep() > > > uncomditionally in rcu_block_is_gp() ? I think it is a bit irrelevant if > > > synchronize_rcu() is called from a call path, before scheduler is > > > initialized, or after. The fact that it was even called from a > > > non-preemptible section is a red-flag, considering if such non-preemptible > > > section may call synchronize_rcu() API in the future, after full boot up, > > > even if rarely. > > > > > > For this reason, IMHO there is still value in doing the might_sleep() check > > > unconditionally. Say if a common code path is invoked both before > > > RCU_SCHEDULER_INIT and *very rarely* after RCU_SCHEDULER_INIT. > > > > > > Or is there more of a point in doing this check if scheduler is initialized > > > from RCU perspective ? > > > > One advantage of its current placement would be if might_sleep() ever > > unconditionally checks for interrupts being disabled. > > > > I don't believe that might_sleep() will do that any time soon given the > > likely fallout from code invoked at early boot as well as from runtime, > > but why be in the way of that additional diagnostic check? > > If I understand the current code, might_sleep() is invoked only if the > scheduler is INACTIVE from RCU perspective, and I don't think here are > reports of fall out. That is current code behavior. > > Situation right now is: might_sleep() only if the state is INACTIVE. > Qiang's patch: might_sleep() only if the state is NOT INACTIVE. > My suggestion: might_sleep() regardless of the state. > > Is there a reason my suggestion will not work? Apologies if I > misunderstood something. > > thanks, > > - Joel > > > > > > Thanx, Paul > > > > > If not, I would do something like this: > > > > > > ---8<----------------------- > > > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > > index 79aea7df4345..23c2303de9f4 100644 > > > --- a/kernel/rcu/tree.c > > > +++ b/kernel/rcu/tree.c > > > @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) > > > { > > > int ret; > > > > > > + might_sleep(); /* Check for RCU read-side critical section. */ > > > + > > > // Invoking preempt_model_*() too early gets a splat. > > > if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || > > > preempt_model_full() || preempt_model_rt()) > > > return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; If the scheduler is inactive (early boot with interrupts disabled), we return here. > > > - might_sleep(); /* Check for RCU read-side critical section. */ We get here only if the scheduler has started, and even then only in preemption-disabled kernels. Or is you concern that the might_sleep() never gets invoked in kernels with preemption enabled? Fixing that would require a slightly different patch, though. Or should I have waited until tomorrow to respond to this email? ;-) Thanx, Paul > > > preempt_disable(); > > > /* > > > * If the rcu_state.n_online_cpus counter is equal to one,
On Sun, Dec 18, 2022 at 2:44 PM Paul E. McKenney <paulmck@kernel.org> wrote: [...] > > > > If not, I would do something like this: > > > > > > > > ---8<----------------------- > > > > > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > > > index 79aea7df4345..23c2303de9f4 100644 > > > > --- a/kernel/rcu/tree.c > > > > +++ b/kernel/rcu/tree.c > > > > @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) > > > > { > > > > int ret; > > > > > > > > + might_sleep(); /* Check for RCU read-side critical section. */ > > > > + > > > > // Invoking preempt_model_*() too early gets a splat. > > > > if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || > > > > preempt_model_full() || preempt_model_rt()) > > > > return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; > > If the scheduler is inactive (early boot with interrupts disabled), > we return here. > > > > > - might_sleep(); /* Check for RCU read-side critical section. */ > > We get here only if the scheduler has started, and even then only in > preemption-disabled kernels. > > Or is you concern that the might_sleep() never gets invoked in kernels > with preemption enabled? Fixing that would require a slightly different > patch, though. > > Or should I have waited until tomorrow to respond to this email? ;-) No, I think you are quite right. I was not referring to rcu_sleep_check(), but rather the following prints in might_sleep(). I see an unconditional call to might_sleep() from kvfree_call_rcu() but not one from synchronize_rcu() which can also sleep. But I see your point, early boot code has interrupts disabled, but can still totally call synchronize_rcu() when the scheduler is INACTIVE. And might_sleep() might bitterly complain. Thanks for the clarification. pr_err("BUG: sleeping function called from invalid context at %s:%d\n", file, line); pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n", in_atomic(), irqs_disabled(), current->non_block_count, current->pid, current->comm); pr_err("preempt_count: %x, expected: %x\n", preempt_count(), offsets & MIGHT_RESCHED_PREEMPT_MASK); Thanks, - Joel > > > > /* > > > > * If the rcu_state.n_online_cpus counter is equal to one,
On Sun, Dec 18, 2022 at 04:02:35PM -0500, Joel Fernandes wrote: > On Sun, Dec 18, 2022 at 2:44 PM Paul E. McKenney <paulmck@kernel.org> wrote: > [...] > > > > > If not, I would do something like this: > > > > > > > > > > ---8<----------------------- > > > > > > > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > > > > index 79aea7df4345..23c2303de9f4 100644 > > > > > --- a/kernel/rcu/tree.c > > > > > +++ b/kernel/rcu/tree.c > > > > > @@ -3435,11 +3435,12 @@ static int rcu_blocking_is_gp(void) > > > > > { > > > > > int ret; > > > > > > > > > > + might_sleep(); /* Check for RCU read-side critical section. */ > > > > > + > > > > > // Invoking preempt_model_*() too early gets a splat. > > > > > if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE || > > > > > preempt_model_full() || preempt_model_rt()) > > > > > return rcu_scheduler_active == RCU_SCHEDULER_INACTIVE; > > > > If the scheduler is inactive (early boot with interrupts disabled), > > we return here. > > > > > > > - might_sleep(); /* Check for RCU read-side critical section. */ > > > > We get here only if the scheduler has started, and even then only in > > preemption-disabled kernels. > > > > Or is you concern that the might_sleep() never gets invoked in kernels > > with preemption enabled? Fixing that would require a slightly different > > patch, though. > > > > Or should I have waited until tomorrow to respond to this email? ;-) > > No, I think you are quite right. I was not referring to > rcu_sleep_check(), but rather the following prints in might_sleep(). I > see an unconditional call to might_sleep() from kvfree_call_rcu() but > not one from synchronize_rcu() which can also sleep. > > But I see your point, early boot code has interrupts disabled, but can > still totally call synchronize_rcu() when the scheduler is INACTIVE. > And might_sleep() might bitterly complain. Thanks for the > clarification. > > pr_err("BUG: sleeping function called from invalid context at %s:%d\n", > file, line); > pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, > name: %s\n", > in_atomic(), irqs_disabled(), current->non_block_count, > current->pid, current->comm); > pr_err("preempt_count: %x, expected: %x\n", preempt_count(), > offsets & MIGHT_RESCHED_PREEMPT_MASK); And I do not believe that we have defined whether or not it is OK to invoke single-argument kvfree_rcu() before the scheduler has started. ;-) Thanx, Paul
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index ee8a6a711719..65f3dd2fd3ae 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3379,9 +3379,10 @@ void __init kfree_rcu_scheduler_running(void) */ static int rcu_blocking_is_gp(void) { - if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) + if (rcu_scheduler_active != RCU_SCHEDULER_INACTIVE) { + might_sleep(); return false; - might_sleep(); /* Check for RCU read-side critical section. */ + } return true; }