Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp3869263ybg; Fri, 25 Oct 2019 10:01:51 -0700 (PDT) X-Google-Smtp-Source: APXvYqy+Tc++audFJ+NPEW+/C4EUUXgyZObUvFIjWczzPYgAZ+20mKtUNAtzd/ACHXZmxhLlyGgp X-Received: by 2002:a50:97af:: with SMTP id e44mr5153990edb.3.1572022911184; Fri, 25 Oct 2019 10:01:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572022911; cv=none; d=google.com; s=arc-20160816; b=IBbvg9R1dYAJ/VsErl9xgdNK/ffzfu34Ziw63ZwbuUjyZzO7dO6rnqE39O8nxYQoAJ VzFWXezuhfZpLyGYwEOxNUd0lLDmer0gD6xnWtt6qZKTaYX4hj5xR/80cCeN4oHiSdzu 6xAjbPc1ZcRoDcL9S7dwQc4W+CLEozcN8OVt1l5sQxPJPv3qLGoZPso4+Ja8ALrBCVzY UmaqmaR18b4IITesj1VQdpk4PUP/yGKdI9aAwm8iZrOWvG32H0Y7tEXjdIdI5l5Jvnv7 uV76OScoRavisoQBynlBc8tU035Sq79f8j7a1OMHxsJWOUac+DuhkVzVnlYvQm9s0pOQ KOwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=S8i+kPsaZWRIBXyQ2g5/YSOuQEjiriODMzIUUPGICqQ=; b=AqYdKU6xeQ74bNQqmXGLHhUZV0qJpXY0ODJSe4sZcObScpCvtk+JEeldaDBvyZVn8M QgWfTuQvFg/Om/DDubjJSpdBz67e7VdujLp39DNCe+O+IoUNI6fmT4KH9eGZpIPFm/v7 0ph1GbF7+L1Fn3kpy5Lbszqyv73cJko5dKwt7Kbz5RU7GvHE+lD/IKweo07Hcn5lnh1w 3qrO40fmWqMDSmid4GUvbLkXabwV/7MbWozupBvWnBHr+XuCbYlW427L5t7W4prrAvqi +U/HDt5w7eaFbE9Q+EhDjaxzVndj+GcYn/RvNI/S4RAhq7ym+AU+944BSTmg1Qedkh2u 1l7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="rjhd/M55"; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 49si1746199edz.9.2019.10.25.10.01.26; Fri, 25 Oct 2019 10:01:51 -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=@google.com header.s=20161025 header.b="rjhd/M55"; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2406052AbfJXOR0 (ORCPT + 99 others); Thu, 24 Oct 2019 10:17:26 -0400 Received: from mail-ot1-f66.google.com ([209.85.210.66]:44247 "EHLO mail-ot1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405890AbfJXOR0 (ORCPT ); Thu, 24 Oct 2019 10:17:26 -0400 Received: by mail-ot1-f66.google.com with SMTP id n48so5858221ota.11 for ; Thu, 24 Oct 2019 07:17:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=S8i+kPsaZWRIBXyQ2g5/YSOuQEjiriODMzIUUPGICqQ=; b=rjhd/M55ZS2DHpPVEyvmw+51VqoZKT+aKpBMcndrlavHNG5q2vOXiJVQS+s8EXv9Dd iCsoOVhsJ+G7gYkpFkn14zYdOpz0vSBpUzDsDu0PBCQ6NzT8xUq5cmrA4xocXCdFwB2z OY76EBmbTCadlVIzDU0S3rEb6LzKAsP2pySsCW8pNgaKuG8yg1KYKhaeOwpjz6pjIre3 ZEktUEMMOiAjH3feXIg6+YO0mzPvWpCriPh+vEPfhR6gnJPhxdJyw0QnglSg76VNRtTS 8IVxVkGqkZRoWCHuKSqjF3oWPtlHkYAoqyjWFNbEZcdU6FuP7HsXigSzaREmQGaHV4Ln 7pkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=S8i+kPsaZWRIBXyQ2g5/YSOuQEjiriODMzIUUPGICqQ=; b=i7aSQ8u1slAitUb5jVK5QJvh5vPbsSWqigFInSG+aLd4GU8md2zP1UzIxKHFWbYJ/B wfDzFmQEEDcsegXPbwlhOZay4JgHzSa24hWBv2I4lyq0fHG62vf+Og6G//gUIUtg9G4C Io62Lt5n195v9j18Gc8CxtwoH8CcFVNKnA5gNcnRJY5lDeSUnmnY1X09l2U8glEnPMo/ uNpePx61QfuyxQxv9Ar+zsG0pSdff7yYYn1rj/ZFrXarL91L0xIg8gvNrjCGuOUnoHZI 8jlz8JBIyx7VBr0xEn+SDO/YFVtQHiDzbRnFxsS/r0UUJQeuAjOlTnlJFjj5ZTwbUtpS qiGw== X-Gm-Message-State: APjAAAXDt5s02+HuOmLH/2ifAUcs2mKDu2zY3D8s/8R8EWRf9iINGrfe Q7w9iZNanP+/O2Y3HqVhGAWZml3Aa8dxaaCM3jo1Fw== X-Received: by 2002:a9d:5f0f:: with SMTP id f15mr11239283oti.251.1571926644575; Thu, 24 Oct 2019 07:17:24 -0700 (PDT) MIME-Version: 1.0 References: <20191017141305.146193-1-elver@google.com> <20191017141305.146193-5-elver@google.com> <20191024122801.GD4300@lakrids.cambridge.arm.com> In-Reply-To: <20191024122801.GD4300@lakrids.cambridge.arm.com> From: Marco Elver Date: Thu, 24 Oct 2019 16:17:11 +0200 Message-ID: Subject: Re: [PATCH v2 4/8] seqlock, kcsan: Add annotations for KCSAN To: Mark Rutland Cc: LKMM Maintainers -- Akira Yokosawa , Alan Stern , Alexander Potapenko , Andrea Parri , Andrey Konovalov , Andy Lutomirski , Ard Biesheuvel , Arnd Bergmann , Boqun Feng , Borislav Petkov , Daniel Axtens , Daniel Lustig , Dave Hansen , David Howells , Dmitry Vyukov , "H. Peter Anvin" , Ingo Molnar , Jade Alglave , Joel Fernandes , Jonathan Corbet , Josh Poimboeuf , Luc Maranget , Nicholas Piggin , "Paul E. McKenney" , Peter Zijlstra , Thomas Gleixner , Will Deacon , kasan-dev , linux-arch , "open list:DOCUMENTATION" , linux-efi@vger.kernel.org, Linux Kbuild mailing list , LKML , Linux Memory Management List , "the arch/x86 maintainers" Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 24 Oct 2019 at 14:28, Mark Rutland wrote: > > On Thu, Oct 17, 2019 at 04:13:01PM +0200, Marco Elver wrote: > > Since seqlocks in the Linux kernel do not require the use of marked > > atomic accesses in critical sections, we teach KCSAN to assume such > > accesses are atomic. KCSAN currently also pretends that writes to > > `sequence` are atomic, although currently plain writes are used (their > > corresponding reads are READ_ONCE). > > > > Further, to avoid false positives in the absence of clear ending of a > > seqlock reader critical section (only when using the raw interface), > > KCSAN assumes a fixed number of accesses after start of a seqlock > > critical section are atomic. > > Do we have many examples where there's not a clear end to a seqlock > sequence? Or are there just a handful? > > If there aren't that many, I wonder if we can make it mandatory to have > an explicit end, or to add some helper for those patterns so that we can > reliably hook them. In an ideal world, all usage of seqlocks would be via seqlock_t, which follows a somewhat saner usage, where we already do normal begin/end markings -- with subtle exception to readers needing to be flat atomic regions, e.g. because usage like this: - fs/namespace.c:__legitimize_mnt - unbalanced read_seqretry - fs/dcache.c:d_walk - unbalanced need_seqretry But anything directly accessing seqcount_t seems to be unpredictable. Filtering for usage of read_seqcount_retry not following 'do { .. } while (read_seqcount_retry(..));' (although even the ones in while loops aren't necessarily predictable): $ git grep 'read_seqcount_retry' | grep -Ev 'seqlock.h|Doc|\* ' | grep -v 'while (' => about 1/3 of the total read_seqcount_retry usage. Just looking at fs/namei.c, I would conclude that it'd be a pretty daunting task to prescribe and migrate to an interface that forces clear begin/end. Which is why I concluded that for now, it is probably better to make KCSAN play well with the existing code. Thanks, -- Marco > Thanks, > Mark. > > > > > Signed-off-by: Marco Elver > > --- > > include/linux/seqlock.h | 44 +++++++++++++++++++++++++++++++++++++---- > > 1 file changed, 40 insertions(+), 4 deletions(-) > > > > diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h > > index bcf4cf26b8c8..1e425831a7ed 100644 > > --- a/include/linux/seqlock.h > > +++ b/include/linux/seqlock.h > > @@ -37,8 +37,24 @@ > > #include > > #include > > #include > > +#include > > #include > > > > +/* > > + * The seqlock interface does not prescribe a precise sequence of read > > + * begin/retry/end. For readers, typically there is a call to > > + * read_seqcount_begin() and read_seqcount_retry(), however, there are more > > + * esoteric cases which do not follow this pattern. > > + * > > + * As a consequence, we take the following best-effort approach for *raw* usage > > + * of seqlocks under KCSAN: upon beginning a seq-reader critical section, > > + * pessimistically mark then next KCSAN_SEQLOCK_REGION_MAX memory accesses as > > + * atomics; if there is a matching read_seqcount_retry() call, no following > > + * memory operations are considered atomic. Non-raw usage of seqlocks is not > > + * affected. > > + */ > > +#define KCSAN_SEQLOCK_REGION_MAX 1000 > > + > > /* > > * Version using sequence counter only. > > * This can be used when code has its own mutex protecting the > > @@ -115,6 +131,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s) > > cpu_relax(); > > goto repeat; > > } > > + kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX); > > return ret; > > } > > > > @@ -131,6 +148,7 @@ static inline unsigned raw_read_seqcount(const seqcount_t *s) > > { > > unsigned ret = READ_ONCE(s->sequence); > > smp_rmb(); > > + kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX); > > return ret; > > } > > > > @@ -183,6 +201,7 @@ static inline unsigned raw_seqcount_begin(const seqcount_t *s) > > { > > unsigned ret = READ_ONCE(s->sequence); > > smp_rmb(); > > + kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX); > > return ret & ~1; > > } > > > > @@ -202,7 +221,8 @@ static inline unsigned raw_seqcount_begin(const seqcount_t *s) > > */ > > static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start) > > { > > - return unlikely(s->sequence != start); > > + kcsan_atomic_next(0); > > + return unlikely(READ_ONCE(s->sequence) != start); > > } > > > > /** > > @@ -225,6 +245,7 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start) > > > > static inline void raw_write_seqcount_begin(seqcount_t *s) > > { > > + kcsan_begin_atomic(true); > > s->sequence++; > > smp_wmb(); > > } > > @@ -233,6 +254,7 @@ static inline void raw_write_seqcount_end(seqcount_t *s) > > { > > smp_wmb(); > > s->sequence++; > > + kcsan_end_atomic(true); > > } > > > > /** > > @@ -262,18 +284,20 @@ static inline void raw_write_seqcount_end(seqcount_t *s) > > * > > * void write(void) > > * { > > - * Y = true; > > + * WRITE_ONCE(Y, true); > > * > > * raw_write_seqcount_barrier(seq); > > * > > - * X = false; > > + * WRITE_ONCE(X, false); > > * } > > */ > > static inline void raw_write_seqcount_barrier(seqcount_t *s) > > { > > + kcsan_begin_atomic(true); > > s->sequence++; > > smp_wmb(); > > s->sequence++; > > + kcsan_end_atomic(true); > > } > > > > static inline int raw_read_seqcount_latch(seqcount_t *s) > > @@ -398,7 +422,9 @@ static inline void write_seqcount_end(seqcount_t *s) > > static inline void write_seqcount_invalidate(seqcount_t *s) > > { > > smp_wmb(); > > + kcsan_begin_atomic(true); > > s->sequence+=2; > > + kcsan_end_atomic(true); > > } > > > > typedef struct { > > @@ -430,11 +456,21 @@ typedef struct { > > */ > > static inline unsigned read_seqbegin(const seqlock_t *sl) > > { > > - return read_seqcount_begin(&sl->seqcount); > > + unsigned ret = read_seqcount_begin(&sl->seqcount); > > + > > + kcsan_atomic_next(0); /* non-raw usage, assume closing read_seqretry */ > > + kcsan_begin_atomic(false); > > + return ret; > > } > > > > static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) > > { > > + /* > > + * Assume not nested: read_seqretry may be called multiple times when > > + * completing read critical section. > > + */ > > + kcsan_end_atomic(false); > > + > > return read_seqcount_retry(&sl->seqcount, start); > > } > > > > -- > > 2.23.0.866.gb869b98d4c-goog > >