Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp923833pxj; Tue, 18 May 2021 17:45:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw4XWTtOmoXmfxYMPeZFmyIdj8JACSzcHfYm+9zhADMPW7NDKd2EuyVXGFYFqs80/Ya1u2b X-Received: by 2002:a92:c54b:: with SMTP id a11mr7330115ilj.174.1621385153749; Tue, 18 May 2021 17:45:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621385153; cv=none; d=google.com; s=arc-20160816; b=sa/pQy00CcMk5Xsr1hyT2mmaOLrV+nhH4PFGRB4dGmMtch/83lFbsfikbwZdDmmdQ4 j4trTH4c3wgE182qMk6lixsZvlPTYr+RV3NHtKTQpx/aWF5+sVLcfTINguSxzeCkMR7R yNenzpFeINK8to1ZUtdO9OywT5U9D1Pi+lV1A4tA/2l8GwKoRcg408jyN3ij5IzyMVNc J+/M+WTa75Cj29YIarXFIBXJV7U+++HdI8g/GrcJ3Ji1Ta2dQ5qNGDAZGWoKgAXET/1y abh4WzxsiAK85KAEbzNIpmjwMixP33Wf9HNgPea9PvJ5Mjim5Np6DWZZtgou2D8mLRd4 V5lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:reply-to:message-id:subject:cc:to:from:date :dkim-signature; bh=DygGXmcskXZHU1KN9XpnDsbytIsPtSEh7zxw83qbKrQ=; b=nqWTIvdWXls1cJkJjk6MQLBR3amsY2RZJQj6HpeZ8rE9md0NnsL6ELukWfbSJGCYTQ cu+/WYZghCUHCgB3bxOdTSlj532l0g8j1wS6T/bQdsi6PJGI3IgRKSmeoxoYnJvSKoGT 7gVJxjTHzo/c6vkztU/zDUcVkJTEbJcucW67148qynv9rE9I1AC9IjkhokIlvw3+L1dS W3e0bGWJ2GOk1nWDF8pWzaFMaha79T47ohs2ts5KgkOMszJorbDie6TrzL89jfceMXel qoOtXb2VqtT/5NkpHPd1GGauUdoYzXUhF4PdttMjFKG2HSrRdo2Qk/7i2EpCHLJbNHAu x69w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="kuH/HHRw"; 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 q186si6818998iof.83.2021.05.18.17.45.14; Tue, 18 May 2021 17:45:53 -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=k20201202 header.b="kuH/HHRw"; 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 S237081AbhEQSdA (ORCPT + 99 others); Mon, 17 May 2021 14:33:00 -0400 Received: from mail.kernel.org ([198.145.29.99]:39898 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237050AbhEQSc7 (ORCPT ); Mon, 17 May 2021 14:32:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id DE86960FD8; Mon, 17 May 2021 18:31:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1621276302; bh=Fxpe+QB7sQgi1r4WTLIIc0qePivJrHj1sVwQWdo0XlA=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=kuH/HHRw116WwoMW9lKI8H1aP/GF0MCSyvx1/MH9CoZLQqUywVAWvP1l6T7NvCMkM dTCShO4ZcZiL9i3vh4L20E+g2e70sHpsUUtYCIqbFdlg6b/h3QARhBwCr8Seka5qSO 3kBEpaRiS+TWsGWb0qCw1merxLwqY/IEAvCIkqdv6loqP7oYQ8uLiY6ZJBxcKJkIcn Tp0edXOOJbx7og1puIA+jYY1yXwOpENZfI0E1grMpSph0ASbMdQOqd1CbD7g+XryEI SP3YFld0m7gOdyeRdeKsW/rCXOTIXHypV+YjsDGLb5/VipnIIpUysjBjJHFhXBdiKZ jTsSC1skfxLRA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A18F95C00C6; Mon, 17 May 2021 11:31:42 -0700 (PDT) Date: Mon, 17 May 2021 11:31:42 -0700 From: "Paul E. McKenney" To: Manfred Spraul Cc: kasan-dev , Linux Kernel Mailing List , Davidlohr Bueso , 1vier1@web.de Subject: Re: ipc/sem, ipc/msg, ipc/mqueue.c kcsan questions Message-ID: <20210517183142.GB2013824@paulmck-ThinkPad-P17-Gen-1> Reply-To: paulmck@kernel.org References: <20210512201743.GW975577@paulmck-ThinkPad-P17-Gen-1> <343390da-2307-442e-8073-d1e779c85eeb@colorfullife.com> <20210513190201.GE975577@paulmck-ThinkPad-P17-Gen-1> <9c9739ec-1273-5137-7b6d-00a27a22ffca@colorfullife.com> <20210514184455.GJ975577@paulmck-ThinkPad-P17-Gen-1> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210514184455.GJ975577@paulmck-ThinkPad-P17-Gen-1> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 14, 2021 at 11:44:55AM -0700, Paul E. McKenney wrote: > On Fri, May 14, 2021 at 07:41:02AM +0200, Manfred Spraul wrote: > > On 5/13/21 9:02 PM, Paul E. McKenney wrote: > > > On Thu, May 13, 2021 at 08:10:51AM +0200, Manfred Spraul wrote: > > > > On 5/12/21 10:17 PM, Paul E. McKenney wrote: [ . . . ] > > > > > int foo; > > > > > DEFINE_RWLOCK(foo_rwlock); > > > > > > > > > > void update_foo(int newval) > > > > > { > > > > > write_lock(&foo_rwlock); > > > > > foo = newval; > > > > > do_something(newval); > > > > > write_unlock(&foo_rwlock); > > > > > } > > > > > > > > > > int read_foo(void) > > > > > { > > > > > int ret; > > > > > > > > > > read_lock(&foo_rwlock); > > > > > do_something_else(); > > > > > ret = foo; > > > > > read_unlock(&foo_rwlock); > > > > > return ret; > > > > > } > > > > > > > > > > int read_foo_diagnostic(void) > > > > > { > > > > > return data_race(foo); > > > > > } > > > > The text didn't help, the example has helped: > > > > > > > > It was not clear to me if I have to use data_race() both on the read and the > > > > write side, or only on one side. > > > > > > > > Based on this example: plain C may be paired with data_race(), there is no > > > > need to mark both sides. > > > Actually, you just demonstrated that this example is quite misleading. > > > That data_race() works only because the read is for diagnostic > > > purposes. I am queuing a commit with your Reported-by that makes > > > read_foo_diagnostic() just do a pr_info(), like this: > > > > > > void read_foo_diagnostic(void) > > > { > > > pr_info("Current value of foo: %d\n", data_race(foo)); > > > } > > > > > > So thank you for that! > > > > I would not like this change at all. > > Assume you chase a rare bug, and notice an odd pr_info() output. > > It will take you really long until you figure out that a data_race() mislead > > you. > > Thus for a pr_info(), I would consider READ_ONCE() as the correct thing. > > It depends, but I agree with a general preference for READ_ONCE() over > data_race(). > > However, for some types of concurrency designs, using a READ_ONCE() > can make it more difficult to enlist KCSAN's help. For example, if this > variable is read or written only while holding a particular lock, so that > read_foo_diagnostic() is the only lockless read, then using READ_ONCE() > adds a concurrent read. In RCU, the updates would now need WRITE_ONCE(), > which would cause KCSAN to fail to detect a buggy lockless WRITE_ONCE(). > If data_race() is used, then adding a buggy lockless WRITE_ONCE() will > cause KCSAN to complain. > > Of course, you would be quite correct to say that this must be balanced > against the possibility of a messed-up pr_info() due to compiler mischief. > Tradeoffs, tradeoffs! ;-) > > I should document this tradeoff, shouldn't I? Except that Marco Elver reminds me that there are two other possibilities: 1. data_race(READ_ONCE(foo)), which both suppresses compiler optimizations and causes KCSAN to ignore the access. 2. "void __no_kcsan read_foo_diagnostic(void)" to cause KCSAN to ignore the entire function, and READ_ONCE() on the access. So things might be the way you want anyway. Does the patch below work for you? Thanx, Paul ------------------------------------------------------------------------ diff --git a/tools/memory-model/Documentation/access-marking.txt b/tools/memory-model/Documentation/access-marking.txt index fe4ad6d12d24..e3012f666e62 100644 --- a/tools/memory-model/Documentation/access-marking.txt +++ b/tools/memory-model/Documentation/access-marking.txt @@ -279,19 +279,34 @@ tells KCSAN that data races are expected, and should be silently ignored. This data_race() also tells the human reading the code that read_foo_diagnostic() might sometimes return a bogus value. -However, please note that your kernel must be built with -CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n in order for KCSAN to -detect a buggy lockless write. If you need KCSAN to detect such a -write even if that write did not change the value of foo, you also -need CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n. If you need KCSAN to -detect such a write happening in an interrupt handler running on the -same CPU doing the legitimate lock-protected write, you also need -CONFIG_KCSAN_INTERRUPT_WATCHER=y. With some or all of these Kconfig -options set properly, KCSAN can be quite helpful, although it is not -necessarily a full replacement for hardware watchpoints. On the other -hand, neither are hardware watchpoints a full replacement for KCSAN -because it is not always easy to tell hardware watchpoint to conditionally -trap on accesses. +If it is necessary to suppress compiler optimization and also detect +buggy lockless writes, read_foo_diagnostic() can be updated as follows: + + void read_foo_diagnostic(void) + { + pr_info("Current value of foo: %d\n", data_race(READ_ONCE(foo))); + } + +Alternatively, given that KCSAN is to ignore all accesses in this function, +this function can be marked __no_kcsan and the data_race() can be dropped: + + void __no_kcsan read_foo_diagnostic(void) + { + pr_info("Current value of foo: %d\n", READ_ONCE(foo)); + } + +However, in order for KCSAN to detect buggy lockless writes, your kernel +must be built with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n. If you +need KCSAN to detect such a write even if that write did not change +the value of foo, you also need CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n. +If you need KCSAN to detect such a write happening in an interrupt handler +running on the same CPU doing the legitimate lock-protected write, you +also need CONFIG_KCSAN_INTERRUPT_WATCHER=y. With some or all of these +Kconfig options set properly, KCSAN can be quite helpful, although +it is not necessarily a full replacement for hardware watchpoints. +On the other hand, neither are hardware watchpoints a full replacement +for KCSAN because it is not always easy to tell hardware watchpoint to +conditionally trap on accesses. Lock-Protected Writes With Lockless Reads