Received: by 2002:a05:7412:a9a2:b0:e2:908c:2ebd with SMTP id o34csp21236rdh; Wed, 25 Oct 2023 14:51:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFdcuzm/iUSE+GcHsmtZvrqlslkH55if8tNpJL+Y8wG55Ldua8xcL4fMKGq8XKpeUqouCIB X-Received: by 2002:a0d:d605:0:b0:592:1bab:52bd with SMTP id y5-20020a0dd605000000b005921bab52bdmr16266876ywd.39.1698270718349; Wed, 25 Oct 2023 14:51:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698270718; cv=none; d=google.com; s=arc-20160816; b=W6yhJrg/C0G/xu2LNHzxFyVwiuv6n80Op8We4l3NnC4RwEJrPilzth1G8kD8BmWb+U H/hYSNEHUjH6836iNqfsjgmMBOZ42pJmjP2wE+ns1JE4LJsJh/I1IB53vzpdtALuhvN3 obL357QgZsYPZDdWIVDt3HcH27LdtMJkh/BkNzCvyiC0k/1ViZ+kAattod2u2dYH08ji 1xXEqzRERb/UcxRfcnAIAgs43Fc/K9+U3ez55qxkotNw6MoHgfA8PnDKX7BDxFc4HhQn uJP8hWlzCAn0QvUMWXeuWlxR9g6fXD2q84nrJBS3tx0p/wQ2wOsjPgtrWAqR99cpdpeO ra3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:dkim-signature; bh=+mIMtJy5g/3pP0bfV4kNM3vtmyjGkqlYbw5iT4J0tl8=; fh=ggmDozqiN9C8oXu2rPiQllu597AeXvgl0k6Pe2ubIM0=; b=TGBMX60GmBEydexMlenjmVaeCiYtNbeq87SxQgzg9r9O9pH2AXcXhDWr5CGYO3WF++ X+3lW7PkuCdJee3m+nApqrT6fY++694DXJEaqUdAZ44sTPfy041DDLrAccxeJQxCjEGx jtDuG68wY6nv78SUfo4XEmk7GY5O8F1rXWjHJDHlSrOoTzhm+z8UxiR7lSr++pZDy3JE 2cSFA0I9ZPiM1WxL+03IbJKtus2iSf4a4jnRsUTmzWW5psUdO/7eaec6JFDGHk2zeZ1t U2aB0BvnjKpxgp/CuTk2Q+vqvX4FtbuQUT/it4YqCuIROfMWOLMNavvZUiVuTzKLNOrH TGWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=iRbIVns0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id i128-20020a0dc686000000b0059f50159dbbsi12856613ywd.574.2023.10.25.14.51.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Oct 2023 14:51:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=iRbIVns0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id D3FB28183EE8; Wed, 25 Oct 2023 14:51:54 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229573AbjJYVvl (ORCPT + 99 others); Wed, 25 Oct 2023 17:51:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230397AbjJYVvj (ORCPT ); Wed, 25 Oct 2023 17:51:39 -0400 Received: from mail-40134.protonmail.ch (mail-40134.protonmail.ch [185.70.40.134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCFF6192; Wed, 25 Oct 2023 14:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1698270694; x=1698529894; bh=+mIMtJy5g/3pP0bfV4kNM3vtmyjGkqlYbw5iT4J0tl8=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=iRbIVns0Dvfe0uo4iphsA8sVRHbI3fybSM6Y3MW1meOEMhMW3SdN9huZmKHpXxX2A oAK5DOYYJZdr4M/kC5NJ+cqGDRzHm0csHrZ4b6h6eWh/WH8RjXWL5YFH4eqIncxgIJ EDkHDM3DRwaW+RxWzN2/5QYQpFRbt83ITw/C427DwracoFThk79D0EYG8u3lo7UpQs FS7NOh7g+xWsN0rozPH61QKY3ppBd5gPVD4R5zuO4AN2dgdGKfGi97VAyLAaXJOs9/ 9+4MysEB0mgU9ipH7wCJyhJkoNKt1bVhQErSz7YIkKG7dA/2UiizCzBeuMdLrL5lPb nu1WNLGiBcOsQ== Date: Wed, 25 Oct 2023 21:51:28 +0000 To: Boqun Feng From: Benno Lossin Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, llvm@lists.linux.dev, Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Alice Ryhl , Alan Stern , Andrea Parri , Will Deacon , Peter Zijlstra , Nicholas Piggin , David Howells , Jade Alglave , Luc Maranget , "Paul E. McKenney" , Akira Yokosawa , Daniel Lustig , Joel Fernandes , Nathan Chancellor , Nick Desaulniers , Tom Rix , Alexander Viro , Christian Brauner , kent.overstreet@gmail.com, Greg Kroah-Hartman , elver@google.com, Matthew Wilcox , Dave Chinner , linux-fsdevel@vger.kernel.org Subject: Re: [RFC] rust: types: Add read_once and write_once Message-ID: In-Reply-To: <20231025195339.1431894-1-boqun.feng@gmail.com> References: <20231025195339.1431894-1-boqun.feng@gmail.com> Feedback-ID: 71780778:user:proton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Wed, 25 Oct 2023 14:51:55 -0700 (PDT) > In theory, `read_volatile` and `write_volatile` in Rust can have UB in > case of the data races [1]. However, kernel uses volatiles to implement I would not write "In theory", but rather state that data races involving `read_volatile` is documented to still be UB. > READ_ONCE() and WRITE_ONCE(), and expects races on these marked accesses Missing "`"? > don't cause UB. And they are proven to have a lot of usages in kernel. >=20 > To close this gap, `read_once` and `write_once` are introduced, they > have the same semantics as `READ_ONCE` and `WRITE_ONCE` especially > regarding data races under the assumption that `read_volatile` and I would separate implementation from specification. We specify `read_once` and `write_once` to have the same semantics as `READ_ONCE` and `WRITE_ONCE`. But we implement them using `read_volatile`/`write_volatile`, so we might still encounter UB, but it is still a sort of best effort. As soon as we have the actual thing in Rust, we will switch the implementation. > `write_volatile` have the same behavior as a volatile pointer in C from > a compiler point of view. >=20 > Longer term solution is to work with Rust language side for a better way > to implement `read_once` and `write_once`. But so far, it should be good > enough. >=20 > Suggested-by: Alice Ryhl > Link: https://doc.rust-lang.org/std/ptr/fn.read_volatile.html#safety [1] > Signed-off-by: Boqun Feng > --- >=20 > Notice I also make the primitives only work on T: Copy, since I don't > think Rust side and C side will use a !Copy type to communicate, but we > can always remove that constrait later. >=20 >=20 > rust/kernel/prelude.rs | 2 ++ > rust/kernel/types.rs | 43 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 45 insertions(+) >=20 > diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs > index ae21600970b3..351ad182bc63 100644 > --- a/rust/kernel/prelude.rs > +++ b/rust/kernel/prelude.rs > @@ -38,3 +38,5 @@ > pub use super::init::{InPlaceInit, Init, PinInit}; >=20 > pub use super::current; > + > +pub use super::types::{read_once, write_once}; Do we really want people to use these so often that they should be in the prelude? Sure there will not really be any name conflicts, but I think an explicit import might make sense. > diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs > index d849e1979ac7..b0872f751f97 100644 > --- a/rust/kernel/types.rs > +++ b/rust/kernel/types.rs I don't think this should go into `types.rs`. But I do not have a good name for the new module. > @@ -432,3 +432,46 @@ pub enum Either { > /// Constructs an instance of [`Either`] containing a value of type = `R`. > Right(R), > } > + > +/// (Concurrent) Primitives to interact with C side, which are considere= d as marked access: > +/// > +/// tools/memory-memory/Documentation/access-marking.txt > + Accidental empty line? Or is this meant as a comment for both functions? > +/// The counter part of C `READ_ONCE()`. > +/// > +/// The semantics is exactly the same as `READ_ONCE()`, especially when = used for intentional data > +/// races. It would be great if these semantics are either linked or spelled out here. Ideally both. > +/// > +/// # Safety > +/// > +/// * `src` must be valid for reads. > +/// * `src` must be properly aligned. > +/// * `src` must point to a properly initialized value of value `T`. > +#[inline(always)] > +pub unsafe fn read_once(src: *const T) -> T { Why only `T: Copy`? > + // SAFETY: the read is valid because of the function's safety requir= ement, plus the assumption > + // here is that 1) a volatile pointer dereference in C and 2) a `rea= d_volatile` in Rust have the > + // same semantics, so this function should have the same behavior as= `READ_ONCE()` regarding > + // data races. I would explicitly state that we might have UB here due to data races. But that we have not seen any invalid codegen and thus assume there to be no UB (you might also want to write this in the commit message). -- Cheers, Benno > + unsafe { src.read_volatile() } > +} > + > +/// The counter part of C `WRITE_ONCE()`. > +/// > +/// The semantics is exactly the same as `WRITE_ONCE()`, especially when= used for intentional data > +/// races. > +/// > +/// # Safety > +/// > +/// * `dst` must be valid for writes. > +/// * `dst` must be properly aligned. > +#[inline(always)] > +pub unsafe fn write_once(dst: *mut T, value: T) { > + // SAFETY: the write is valid because of the function's safety requi= rement, plus the assumption > + // here is that 1) a write to a volatile pointer dereference in C an= d 2) a `write_volatile` in > + // Rust have the same semantics, so this function should have the sa= me behavior as > + // `WRITE_ONCE()` regarding data races. > + unsafe { > + core::ptr::write_volatile(dst, value); > + } > +} > -- > 2.41.0