Received: by 2002:a25:2c96:0:0:0:0:0 with SMTP id s144csp196657ybs; Tue, 26 May 2020 07:05:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyCA5P96orgCZrV4JQ3D2yw89afKreSehl3N5ZUTOo8mThN0nu7D4OZsvxKLWcipzTtzSuZ X-Received: by 2002:aa7:d3d6:: with SMTP id o22mr20448436edr.359.1590501936975; Tue, 26 May 2020 07:05:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590501936; cv=none; d=google.com; s=arc-20160816; b=ju5SxacZxitmpUuwWC9VD+dPQCYONeez+VwQgI+lMM2vezyB5NXv1smHPeCobbSKkc XqkSv6hiZyl8OeaSH4l+FPx5yh3YShGRcCHmyfLS0Q2XUV/tQ6zYDNZQCdRl00+G9Qxc ofQas46uBObVUDrS0VevvUcE0mK/h9REDS6GfEFHHPLDMrCr937ekJDO5avBn7kqKxe2 n/IJ7RsTy08rDZWnRjyDtfrw7/S7ZbDDKYVs5GTF0BXFYdxi+9Cwzz37j8M1ZGfeXDTH Wgt/q9oz0K1PGNc6ph34gEpfXfzNzj5fBrJdBSEu0ejzCgVXajVeqYoxtpyY6IqPP1Xy HbnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=/vLjQnkOHotNrUohfz6dirbgajvGz3Sjs7n+kk6JQxI=; b=ajiCtpiwYSgRcO2AZOgrhRTNXH0924J4/we1yMPMgKwbhjVfk9Ye8lHUf1BoO4K8Mj ThwBQZBq5i3l8Cd2eaLkYJFUArrvZKQE/2FzkCd8WkMER4D0lRVLoTsC7INLrDNaNIgP emhV8cuZ7o9cIf3GXpogqu3oiV8EY7DLsuO3BeS07gHCMJ0EYv/ml2m4TXvOWtm7OXab WgER5qbdthsG2Zhd9xoF+zA7TjxEo/Vs3y9DO+iWH+zjxDJT9RIFafw05MsbPLS3YUWf abcWKoyimLWK+0+oAIaLUJFXtr36EBxyh/A3mzTmZoF/PmF/KNedl2ghtSg+osgwdjVo YQWQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z11si11818306ejj.115.2020.05.26.07.05.07; Tue, 26 May 2020 07:05:36 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731737AbgEZNmL (ORCPT + 99 others); Tue, 26 May 2020 09:42:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727864AbgEZNmL (ORCPT ); Tue, 26 May 2020 09:42:11 -0400 Received: from Galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA0E2C03E96D; Tue, 26 May 2020 06:42:10 -0700 (PDT) Received: from bigeasy by Galois.linutronix.de with local (Exim 4.80) (envelope-from ) id 1jdZpn-0003ZA-0O; Tue, 26 May 2020 15:41:35 +0200 Date: Tue, 26 May 2020 15:41:34 +0200 From: Sebastian Andrzej Siewior To: "Paul E. McKenney" Cc: Peter Zijlstra , linux-kernel@vger.kernel.org, Ingo Molnar , Steven Rostedt , Will Deacon , Thomas Gleixner , Linus Torvalds , Lai Jiangshan , Josh Triplett , Mathieu Desnoyers , rcu@vger.kernel.org Subject: [PATCH] srcu: Avoid local_irq_save() before acquiring spinlock_t Message-ID: <20200526134134.5uq62linhbog43q3@linutronix.de> References: <20200519201912.1564477-1-bigeasy@linutronix.de> <20200519201912.1564477-4-bigeasy@linutronix.de> <20200520102407.GF317569@hirez.programming.kicks-ass.net> <20200520120608.mwros5jurmidxxfv@linutronix.de> <20200520184345.GU2869@paulmck-ThinkPad-P72> <20200522151255.rtqnuk2cl3dpruou@linutronix.de> <20200522173953.GI2869@paulmck-ThinkPad-P72> <20200523150831.wdrthklakwm6wago@linutronix.de> <20200524190356.eqohmrmbilonm4u7@linutronix.de> <20200525032717.GV2869@paulmck-ThinkPad-P72> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20200525032717.GV2869@paulmck-ThinkPad-P72> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org SRCU disables interrupts to get a stable per-CPU pointer and then acquires the spinlock which is in the per-CPU data structure. The release uses spin_unlock_irqrestore(). While this is correct on a non-RT kernel, this conflicts with the RT semantics because the spinlock is converted to a 'sleeping' spinlock. Sleeping locks can obviously not be acquired with interrupts disabled. Acquire the per-CPU pointer `ssp->sda' without disabling preemption and then acquire the spinlock_t of the per-CPU data structure. The lock will ensure that the data is consistent. The added check_init_srcu_struct() is now needed because a statically defined srcu_struct may remain uninitialized until this point and the newly introduced locking operation requires an initialized spinlock_t. This change was tested for four hours with 8*SRCU-N and 8*SRCU-P without causing any warnings. Cc: Lai Jiangshan Cc: "Paul E. McKenney" Cc: Josh Triplett Cc: Steven Rostedt Cc: Mathieu Desnoyers Cc: rcu@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- kernel/rcu/srcutree.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 0c71505f0e19c..9459bca58c380 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -764,14 +764,15 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp) unsigned long t; unsigned long tlast; + check_init_srcu_struct(ssp); /* If the local srcu_data structure has callbacks, not idle. */ - local_irq_save(flags); - sdp = this_cpu_ptr(ssp->sda); + sdp = raw_cpu_ptr(ssp->sda); + spin_lock_irqsave_rcu_node(sdp, flags); if (rcu_segcblist_pend_cbs(&sdp->srcu_cblist)) { - local_irq_restore(flags); + spin_unlock_irqrestore_rcu_node(sdp, flags); return false; /* Callbacks already present, so not idle. */ } - local_irq_restore(flags); + spin_unlock_irqrestore_rcu_node(sdp, flags); /* * No local callbacks, so probabalistically probe global state. @@ -851,9 +852,8 @@ static void __call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp, } rhp->func = func; idx = srcu_read_lock(ssp); - local_irq_save(flags); - sdp = this_cpu_ptr(ssp->sda); - spin_lock_rcu_node(sdp); + sdp = raw_cpu_ptr(ssp->sda); + spin_lock_irqsave_rcu_node(sdp, flags); rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp); rcu_segcblist_advance(&sdp->srcu_cblist, rcu_seq_current(&ssp->srcu_gp_seq)); -- 2.27.0.rc0