Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp732854ybz; Wed, 15 Apr 2020 17:46:07 -0700 (PDT) X-Google-Smtp-Source: APiQypLk7/b7x0iCw3UCVSCB64rsTKv5VzcvnlphNNCKfj7xyloWl88VZhyQBOc0+eHhlr7MenMu X-Received: by 2002:a17:906:412:: with SMTP id d18mr7018122eja.54.1586997967654; Wed, 15 Apr 2020 17:46:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586997967; cv=none; d=google.com; s=arc-20160816; b=GFR2z7vi1A73DA02KNQQ+Zo4SFoNs76ONF8y+LuMfn1HOu7N2L96m0YlTeJGFDnzrM /RgEDB6Wfy+hnHWJqMw8nyxe03n+pfaMjfcjxA7jthuHBApYj1hZ5MY56R1t3t+H/A4V Cm00ieUNhmEQWBtaaSO7s+ApeQEBL1vFqbswtndo0XI9lhPb3AklsLFPFvU4LjJnhwFj I7T0AZ/jEc8AWwwvlB5TcE7RgtRHVWhJcz1w+X+jC6vVSQU2QpVzGTXWyIc+b4IprTBu etaueDr8f0YJJSB0i5AnC0WOr20TAWClXqnBXWD6i3EN2YAsRkvWNak2+Ut3/DNaNoDB x/Tg== 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=FXuuZw4zFzCRRH5RnLJ5zThRhTIUVGviQz85tHAMhEY=; b=vKSqnBE5JNzDfMb+c+80awvwxui1iNGJ3w27f32mDFv1IggtsTv2VyfRTN2gaQx66P kwtZRtZ4URMzMlR9zI9xXE0qwNbppLvdZIZmIk1+VbfQ55nGyc1pedr1EhVVeqbPWKYL /Z2OkZe0RnQ3XW10OkeErgCNtE9x7O642xz5LYEs/4wB9/2tjwqMvfOVNxw2G8hQqOhk yLHp5TdDhJcX4LyZkptRRiqX1Yl9rICfN4iKybAa7uoXPhu+TlC2i0Pk6LlZzDqXW3WL pUP4iKmy23RHXIuvibtFa77kMH+jvFsclVj0wRnsYfjaoIES02+kkp1pR4gW6xirtuFh Z1Rg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=vza0tVvL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id bi17si11956053edb.370.2020.04.15.17.45.43; Wed, 15 Apr 2020 17:46:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=vza0tVvL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S2441411AbgDOSUE (ORCPT + 99 others); Wed, 15 Apr 2020 14:20:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:36954 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436610AbgDOSTp (ORCPT ); Wed, 15 Apr 2020 14:19:45 -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 826BF20771; Wed, 15 Apr 2020 18:19:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586974783; bh=WX3rvK+KLjoJ4P6nj6Msiv1bQF5K85x4Dor+mT2zmIo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vza0tVvLxzjXJDxYh+WJDdtWoKWdKjH/k6qGPBSZZl7mfkBuvr9b6Wz+XQHBGs3cH tHqfuDXacGNV8vWprT8hcGJ1hIb5QBYJGTbhgDbxm9viJDfdLDgTrFo2yvLdugDxMt JhYZD3IHYS4vZ0gHYNeiEvGge81GtCbpnXDFbdoE= 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 v4 tip/core/rcu 01/38] rcu: Add comments marking transitions between RCU watching and not Date: Wed, 15 Apr 2020 11:19:04 -0700 Message-Id: <20200415181941.11653-1-paulmck@kernel.org> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200415181856.GA11037@paulmck-ThinkPad-P72> References: <20200415181856.GA11037@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 f13130a..e54a8a1 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -238,7 +238,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) { @@ -251,7 +253,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! */ @@ -261,7 +263,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) { @@ -274,6 +277,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) { @@ -584,6 +588,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; } @@ -596,7 +601,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(); } @@ -676,7 +683,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(); @@ -751,11 +760,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)); @@ -832,7 +844,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(); @@ -842,9 +856,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