Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp1208590ybh; Thu, 12 Mar 2020 19:41:32 -0700 (PDT) X-Google-Smtp-Source: ADFU+vuRr2OrbKF5KYfs/yZqhLAGXc3flTBiCBIVMl1zA41s3IXo6BFGhxdC/CY9o7VnOuSPK+xv X-Received: by 2002:aca:be09:: with SMTP id o9mr5344578oif.177.1584067291970; Thu, 12 Mar 2020 19:41:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584067291; cv=none; d=google.com; s=arc-20160816; b=Er0ffl2byM9mVrPL+uPIOVOZSv6Jh2YvqaXijCXr8Ga9UUoKxEATzhdfGNo8WDNKl8 FebFPgwSlUvmtRwGPhxm+LuCHVNwuLqaUOAI+E4ah2MQwcIzbTpVdb4DKqH16ed1lqWf bqn474GN2rJSus+4o+XV4v0y1YJX7roPtz/bdlZ3fCfE/efAvcDursQSWjFBK/XmKpus N/7ONq6rKsI9TWH/19xnyDrtez6HXfNkOZGM7PvmgJSGEVen3t5od0NMkuTokUNedj45 R40zCgxfsj5Hjc9WU8DzHahlF3TNcSwgWljASsPDOyKVngUDJzvYkiENWIMtGG3uxGL8 LnQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=BSsB5mDo+iSKbP0dC/Y4SbLFYUXWpfThUFKaZ/4HX7g=; b=TlTfdRqfub0pkHayWe6iyyKN1OHqSps82opbazwBYsE85RUUV9mg0BgND4rZrNDhl6 IrnAt2wn60Ls/5rgJ78cgFFGTUieMB4m7c/s/XTOdM56nUhjyVxvIURrzX4MezPaBKO0 IZSnfZdL99pc2UyEpy7Fx6x3vaG7AkBw3/app5EJX/5AhleqshkwARJf0yn5UmihYH+a 3NQ3vi9NfHJkZ9iijbvgXLXuNLPNtQe0KICXihfjWpnb+q1tR6JTsApAij0+vS2L9vEQ F78teniQ1e2nn6cr94u1XEpY/xFMGSVzMocfZCau8KGHEquKvZwDer8t3iumpQ3Q3M2f zu/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=wOJlgan3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p25si3844789oto.168.2020.03.12.19.41.19; Thu, 12 Mar 2020 19:41:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=wOJlgan3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726545AbgCMCkt (ORCPT + 99 others); Thu, 12 Mar 2020 22:40:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:57680 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726246AbgCMCks (ORCPT ); Thu, 12 Mar 2020 22:40:48 -0400 Received: from paulmck-ThinkPad-P72.home (50-39-105-78.bvtn.or.frontiernet.net [50.39.105.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1B95E2073B; Fri, 13 Mar 2020 02:40:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1584067248; bh=M76NEENupVehXA7TGC3d9xvQsRxSR1zMhVkA5XMsdsE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wOJlgan3gBFU1jxmFLXVMnQRX1LclFoGfDqBKbBus7JmwhmBDFJKqzFC+9i/RpahC 1+KxEYfXELrRLOAeraSauiPvnjzAyqtL3/gUx2DXjfbk/Ho6L5tJC9x/Ivz+MXkteb RcUQtcVLNigX6yqPJiLZpGvL8PZRXlCgk3CG3nfg= From: paulmck@kernel.org To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@fb.com, mingo@kernel.org, jiangshanlai@gmail.com, dipankar@in.ibm.com, akpm@linux-foundation.org, mathieu.desnoyers@efficios.com, josh@joshtriplett.org, tglx@linutronix.de, peterz@infradead.org, rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com, fweisbec@gmail.com, oleg@redhat.com, joel@joelfernandes.org, "Paul E. McKenney" Subject: [PATCH RFC tip/core/rcu 2/2] rcu: Add comments marking transitions between RCU watching and not Date: Thu, 12 Mar 2020 19:40:46 -0700 Message-Id: <20200313024046.27622-2-paulmck@kernel.org> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200313024007.GA27492@paulmck-ThinkPad-P72> References: <20200313024007.GA27492@paulmck-ThinkPad-P72> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Paul E. McKenney" It is not as clear as it might be just where in RCU's idle entry/exit code RCU stops and starts watching the current CPU. This commit therefore adds comments calling out the transitions. Reported-by: Thomas Gleixner Signed-off-by: Paul E. McKenney --- kernel/rcu/tree.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index f7d3e48..2f4c91a 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -225,7 +225,9 @@ void rcu_softirq_qs(void) /* * Record entry into an extended quiescent state. This is only to be - * called when not already in an extended quiescent state. + * called when not already in an extended quiescent state, that is, + * RCU is watching prior to the call to this function and is no longer + * watching upon return. */ static void rcu_dynticks_eqs_enter(void) { @@ -238,7 +240,7 @@ static void rcu_dynticks_eqs_enter(void) * next idle sojourn. */ seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks); - /* Better be in an extended quiescent state! */ + // RCU is no longer watching. Better be in extended quiescent state! WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && (seq & RCU_DYNTICK_CTRL_CTR)); /* Better not have special action (TLB flush) pending! */ @@ -248,7 +250,8 @@ static void rcu_dynticks_eqs_enter(void) /* * Record exit from an extended quiescent state. This is only to be - * called from an extended quiescent state. + * called from an extended quiescent state, that is, RCU is not watching + * prior to the call to this function and is watching upon return. */ static void rcu_dynticks_eqs_exit(void) { @@ -261,6 +264,7 @@ static void rcu_dynticks_eqs_exit(void) * critical section. */ seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks); + // RCU is now watching. Better not be in an extended quiescent state! WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !(seq & RCU_DYNTICK_CTRL_CTR)); if (seq & RCU_DYNTICK_CTRL_MASK) { @@ -571,6 +575,7 @@ static void rcu_eqs_enter(bool user) WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && rdp->dynticks_nesting == 0); if (rdp->dynticks_nesting != 1) { + // RCU will still be watching, so just do accounting and leave. rdp->dynticks_nesting--; return; } @@ -583,7 +588,9 @@ static void rcu_eqs_enter(bool user) rcu_prepare_for_idle(); rcu_preempt_deferred_qs(current); WRITE_ONCE(rdp->dynticks_nesting, 0); /* Avoid irq-access tearing. */ + // RCU is watching here ... rcu_dynticks_eqs_enter(); + // ... but is no longer watching here. rcu_dynticks_task_enter(); } @@ -663,7 +670,9 @@ static __always_inline void rcu_nmi_exit_common(bool irq) if (irq) rcu_prepare_for_idle(); + // RCU is watching here ... rcu_dynticks_eqs_enter(); + // ... but is no longer watching here. if (irq) rcu_dynticks_task_enter(); @@ -738,11 +747,14 @@ static void rcu_eqs_exit(bool user) oldval = rdp->dynticks_nesting; WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); if (oldval) { + // RCU was already watching, so just do accounting and leave. rdp->dynticks_nesting++; return; } rcu_dynticks_task_exit(); + // RCU is not watching here ... rcu_dynticks_eqs_exit(); + // ... but is watching here. rcu_cleanup_after_idle(); trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, atomic_read(&rdp->dynticks)); WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current)); @@ -819,7 +831,9 @@ static __always_inline void rcu_nmi_enter_common(bool irq) if (irq) rcu_dynticks_task_exit(); + // RCU is not watching here ... rcu_dynticks_eqs_exit(); + // ... but is watching here. if (irq) rcu_cleanup_after_idle(); @@ -829,9 +843,16 @@ static __always_inline void rcu_nmi_enter_common(bool irq) rdp->dynticks_nmi_nesting == DYNTICK_IRQ_NONIDLE && READ_ONCE(rdp->rcu_urgent_qs) && !READ_ONCE(rdp->rcu_forced_tick)) { + // We get here only if we had already exited the extended + // quiescent state and this was an interrupt (not an NMI). + // Therefore, (1) RCU is already watching and (2) The fact + // that we are in an interrupt handler and that the rcu_node + // lock is an irq-disabled lock prevents self-deadlock. + // So we can safely recheck under the lock. raw_spin_lock_rcu_node(rdp->mynode); - // Recheck under lock. if (rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) { + // A nohz_full CPU is in the kernel and RCU + // needs a quiescent state. Turn on the tick! WRITE_ONCE(rdp->rcu_forced_tick, true); tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU); } -- 2.9.5