Received: by 2002:ab2:3319:0:b0:1ef:7a0f:c32d with SMTP id i25csp251990lqc; Thu, 7 Mar 2024 17:00:08 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCV0/h/4kEXlgv9xV+ZFW/io8zReTzO1JCPM/R1akylVGK2uQu1LqDkWT7wnxseGl8Yzz2NcIiAyJ7wf7cNOI0YH7UBTeYdkhPgHEZ48Ug== X-Google-Smtp-Source: AGHT+IGQDZCERS9rLf/shiRu44gbWs3YAcOzFJ33OgINddPCN2OhUJHGsQh2Gp96BApWxwOWPLuB X-Received: by 2002:a0c:e353:0:b0:690:97ed:fe30 with SMTP id a19-20020a0ce353000000b0069097edfe30mr5291641qvm.30.1709859608671; Thu, 07 Mar 2024 17:00:08 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709859608; cv=pass; d=google.com; s=arc-20160816; b=UhMoSpwiD6fGjCDES00UMKX9kF9/w4WOZpmFyHXGlv67K/JTxV5xbyuybyGW87vGdm Rmlxo9tXuFSdUyK30EafEwb0no5NKqI681WNOy+MQmK61xmufmfBQON41k1uE4Gp59Gj tOVw+9TJEgV1Pf1o+4SZdY0m7sYyW2whxuCLqHd50/ZqKx+mA5xi/qKLCutPlr0JdL9E YVLEtQwSNWS9Nh/9ntwCzaDmN2Q42hG7FSqs+fDe0tzhLCtYCj1M6GMiN4UGjUHyFHQD IQ5OMC+7EG4lHfAfDoF76OjhBsVrtA+2k45cCu6KkdafSFvISakQOf5627tkmouukFNf Mu/g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=ji8QDnmMScW/JPDqUkjSxKbFGFV1DrudmlYGaqcQrEc=; fh=x4jX7DJCpIoNFusqnt1UOCguYaNLis+cTWSDT907oSM=; b=U1fZ2vsYDKu2GOWxzW3M4RN4VkDm1G2GGg6OJgYA4Crf8PpLGEC33SSrPOKK0GN9nJ Q/v9kiNCeeyWSk2fnWNR05uM7TbyzqgWNASiVj+YyQmtXd3PJ+AJefgI7zBuR+gskkar 7B7bCR+q5nDYbcw3evnhAQo9iwTag3N8Jn663kEV0XE39YE0JE4cS3WsHs9J/Mc5EeY2 8IH2EPci7jQxucHRJajWa/cr0+Ja8JLxjZvp/q5o/qJgkTcwIRUltXi+BnNiH4D1LviZ 7a3Uon5ArXgSRql7lnk5y0qP46WV7MhhZZ6sm6JXS1yYxHJbNPOQIsqGGoXZeH82DoBG PBHA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=JiwTGHVO; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-96409-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-96409-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id i7-20020ad45c67000000b0068fd0486f10si18252548qvh.51.2024.03.07.17.00.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Mar 2024 17:00:08 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-96409-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=JiwTGHVO; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-96409-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-96409-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5958D1C20E70 for ; Fri, 8 Mar 2024 01:00:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 69A7A224DA; Fri, 8 Mar 2024 00:58:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JiwTGHVO" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 61839219F0; Fri, 8 Mar 2024 00:58:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709859531; cv=none; b=WjCX87rSzCx12UdP5Y/kvU2PbsmgUB7d7t9CInGVa5/c12INMN/LKCj65V6/xB5aTXM3+3HtTIO1OmK8g1+tp4CY6t5/RJ7/zZxe52T5J2Xyu3xy6ZvPEV/3j7mPlYXkzKVhRshacyw10yastFNOnwozMW7Gzb9vYYGSi0NTcIM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709859531; c=relaxed/simple; bh=ZPyNgw50IlMj3ZZ9BFxPHhxLNMbM6ym6HoTafz/JF0c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=oGWubKew99022mTMS2qqNk84+L+R7ATCUbgdKJaPnhimX2cDNdOsb2+KBK2L+V3DjLJM6LAftOMdxImELLh7riLHkc1CBsDBznZ6TUFLfaybj/80LySazH5ZO3PMRLOn2vQrkwov6ZfwF8jqbzYS73nRwMBXc0pqGduR3cf7jDM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JiwTGHVO; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id C65F8C433F1; Fri, 8 Mar 2024 00:58:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1709859530; bh=ZPyNgw50IlMj3ZZ9BFxPHhxLNMbM6ym6HoTafz/JF0c=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=JiwTGHVOguV9FSNQ3ANzjq1D6UTnKbnaJQNIOVCH/xER5PeTG+JaUxQABsm2Mwx42 PPxUQuNiZv6HWLrOzIj5/6V/ShiiB4Mhd1Ehlh7zLvprQLRiIPkzOjj/T4LfxxVY8V NM35WC+MxQRvwyS7aGtc1jeeMgtLOSIdQen6xcIOESgHunqq9mE2OLGkWJsOSETous pk8CVatOWHLjZDzSouDyikl8lCNRyLGEGGiePtKV7URo5KvRWjb/fotsoH+qw07maA wuD62nRBDbnstHtgTSwblP9Am2fbYo7BeZWu2om1PwmxKiZMx8LoZrclg5EdmDG+qC Lg63C/OnC+RDA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 6D32ACE0716; Thu, 7 Mar 2024 16:58:50 -0800 (PST) Date: Thu, 7 Mar 2024 16:58:50 -0800 From: "Paul E. McKenney" To: Mathieu Desnoyers Cc: Linus Torvalds , Steven Rostedt , linke li , joel@joelfernandes.org, boqun.feng@gmail.com, dave@stgolabs.net, frederic@kernel.org, jiangshanlai@gmail.com, josh@joshtriplett.org, linux-kernel@vger.kernel.org, qiang.zhang1211@gmail.com, quic_neeraju@quicinc.com, rcu@vger.kernel.org Subject: Re: [PATCH] rcutorture: Fix rcu_torture_pipe_update_one()/rcu_torture_writer() data race and concurrency bug Message-ID: Reply-To: paulmck@kernel.org References: <20240306142738.7b66a716@rorschach.local.home> <83b47424-e5e0-46de-aa63-d413a5aa6cec@paulmck-laptop> <851dc594-d2ea-4050-b7c6-e33a1cddf3a1@efficios.com> <72b14322-78c1-4479-9c4e-b0e11c1f0d53@paulmck-laptop> <2721d70f-67a8-428f-903b-1c7c6c6da7f9@efficios.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <2721d70f-67a8-428f-903b-1c7c6c6da7f9@efficios.com> On Thu, Mar 07, 2024 at 02:53:43PM -0500, Mathieu Desnoyers wrote: > On 2024-03-07 14:47, Paul E. McKenney wrote: > > On Thu, Mar 07, 2024 at 08:53:05AM -0500, Mathieu Desnoyers wrote: > > > On 2024-03-06 22:37, Paul E. McKenney wrote: > > > > On Wed, Mar 06, 2024 at 10:06:21PM -0500, Mathieu Desnoyers wrote: > > > [...] > > > > > > > > > As far as the WRITE_ONCE(x, READ_ONCE(x) + 1) pattern > > > > > is concerned, the only valid use-case I can think of is > > > > > split counters or RCU implementations where there is a > > > > > single updater doing the increment, and one or more > > > > > concurrent reader threads that need to snapshot a > > > > > consistent value with READ_ONCE(). > > > > > > > [...] > > > > > > > > So what would you use that pattern for? > > > > > > > > One possibility is a per-CPU statistical counter in userspace on a > > > > fastpath, in cases where losing the occasional count is OK. Then learning > > > > your CPU (and possibly being immediately migrated to some other CPU), > > > > READ_ONCE() of the count, increment, and WRITE_ONCE() might (or might not) > > > > make sense. > > > > > > > > I suppose the same in the kernel if there was a fastpath so extreme you > > > > could not afford to disable preemption. > > > > > > > > At best, very niche. > > > > > > > > Or am I suffering a failure of imagination yet again? ;-) > > > > > > The (niche) use-cases I have in mind are split-counters and RCU > > > grace period tracking, where precise counters totals are needed > > > (no lost count). > > > > > > In the kernel, this could be: > > > > Thank you for looking into this! > > > > > - A per-cpu counter, each counter incremented from thread context with > > > preemption disabled (single updater per counter), read concurrently by > > > other threads. WRITE_ONCE/READ_ONCE is useful to make sure there > > > is no store/load tearing there. Atomics on the update would be stronger > > > than necessary on the increment fast-path. > > > > But if preemption is disabled, the updater can read the value without > > READ_ONCE() without risk of concurrent update. Or are you concerned about > > interrupt handlers? This would have to be a read from the interrupt > > handler, given that an updated from the interrupt handler could result > > in a lost count. > > You are correct that the updater don't need READ_ONCE there. It would > however require a WRITE_ONCE() to match READ_ONCE() from concurrent > reader threads. > > > > > > - A per-thread counter (e.g. within task_struct), only incremented by the > > > single thread, read by various threads concurrently. > > > > Ditto. > > Right, only WRITE_ONCE() on the single updater, READ_ONCE() on readers. > > > > > > - A counter which increment happens to be already protected by a lock, read > > > by various threads without taking the lock. (technically doable, but > > > I'm not sure I see a relevant use-case for it) > > > > In that case, the lock would exclude concurrent updates, so the lock > > holder would not need READ_ONCE(), correct? > > Correct. > > > > > > In user-space: > > > > > > - The "per-cpu" counter would have to use rseq for increments to prevent > > > inopportune migrations, which needs to be implemented in assembler anyway. > > > The counter reads would have to use READ_ONCE(). > > > > Fair enough! > > > > > - The per-thread counter (Thread-Local Storage) incremented by a single > > > thread, read by various threads concurrently, is a good target > > > for WRITE_ONCE()/READ_ONCE() pairing. This is actually what we do in > > > various liburcu implementations which track read-side critical sections > > > per-thread. > > > > Agreed, but do any of these use WRITE_ONCE(x, READ_ONCE(x) + 1) or > > similar? > > Not quite, I recall it's more like WRITE_ONCE(x, READ_ONCE(y)) or such, > so we can grab the value of the current gp counter and store it into a > TLS variable. Good point, you could use that pattern to grab a shared snapshot. Still sounds niche, but you never know! ;-) Thanx, Paul > > > - Same as for the kernel, a counter increment protected by a lock which > > > needs to be read from various threads concurrently without taking > > > the lock could be a valid use-case, though I fail to see how it is > > > useful due to lack of imagination on my part. ;-) > > > > In RCU, we have "WRITE_ONCE(*sp, *sp + 1)" for this use case, though > > here we have the WRITE_ONCE() but not the READ_ONCE() because we hold > > the lock excluding any other updates. > > You are right, the READ_ONCE() is not needed in this case for the > updater, only for the concurrent readers. > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > EfficiOS Inc. > https://www.efficios.com >