From patchwork Wed Dec 28 06:03:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37105 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1738383wrt; Tue, 27 Dec 2022 22:05:08 -0800 (PST) X-Google-Smtp-Source: AMrXdXswyRoYN/nK+VCFclmt6Lv1cKNlQGX6JiwI3S3xboY55XnN7MxN/zKjFt03QbXyKK7L4AKA X-Received: by 2002:a17:90a:244:b0:219:94b2:78a with SMTP id t4-20020a17090a024400b0021994b2078amr26647114pje.30.1672207508496; Tue, 27 Dec 2022 22:05:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207508; cv=none; d=google.com; s=arc-20160816; b=GHNwel6eUA/UzEQNlR8vCKEwrZhthkQNU5ooeKEKB2+PuitgllSm7ejILPtwO7b5Mq CW1JnkkSL3rzmy/SrzV+qsqknNW+Xlp7+s9s6iQsd56EgREoiEwEY5uVSHbycjWPIyew W5qGJsNYyB9s+6n/77eOn0Z8/I5VsuMTjWznQFHNNPSiuySCqFUsvnCb+HVpgUfLeC2Q ScHJWWRTCq8MvBHQR6p1fsT6e5s0hzQsy/QlLqHji8rJ11fxUv8EvbWSYYZ3aAgAaODZ z3ch1VlBS6KbY/JtIiraxRsQ+ka1eLqpFWa75ZaO5zaqqgQKSHHiQEpFd7TYQAARZ1Xk u6sQ== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=gRIFFRiWtKhehgMZp5r2SWnueOlS4dTgUKCwXFukHZk=; b=uzXOyeittvUf9D+nJI5lPdrTjndDstPTR29D/EaNAnw98TqHNBWultA81YGZdXYjRi SwQlbQ6LFztkLa878B7UJ9T319srwyl5+KB0eB+h9Nshna4LHZZWllvwlBOUM+szYTHZ oSxPnkBmOyG9a3+hzIC1szMC2gliW47sHZlTkecvQ9zjJqSAoRVxy6Xpso2wmhV86bHH 295h7MPJvfEtlXjoC7xEojH7JHKyWFhu4J9ytStUkEAPr5I4vCELXkF/U7sW90i6Yw/T kph63V8+upSXSXIaI8/FdrOg+kBrOoui8qzksF+WpU1PRTH36wBAtf8TO41Vf14G2TEe hRjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=AphQNvib; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ls10-20020a17090b350a00b002192a6c09d5si11420999pjb.10.2022.12.27.22.04.56; Tue, 27 Dec 2022 22:05:08 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=AphQNvib; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229668AbiL1GEo (ORCPT + 99 others); Wed, 28 Dec 2022 01:04:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229468AbiL1GEi (ORCPT ); Wed, 28 Dec 2022 01:04:38 -0500 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01337DEFD; Tue, 27 Dec 2022 22:04:36 -0800 (PST) Received: by mail-wr1-x433.google.com with SMTP id h16so14046839wrz.12; Tue, 27 Dec 2022 22:04:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=gRIFFRiWtKhehgMZp5r2SWnueOlS4dTgUKCwXFukHZk=; b=AphQNvib3d7n3b7NiAUKifYkeUSItHpgkIzA5zXVf6T64S2O/FLo2wG2knvFLrtvr5 3jx+RIDnT8Eko3zxpuxKn+6c4jCPWpIUpy0ga49EGt4C9clKJACj6GBihfHFbCCH1I1F 2+I+VfT6RDAu0UmGn8gDxB9+xcEUoFY5FekqUtZ+bJpF2rIt2IOc642gBuMAezKwp3L1 0Wh8L4Cm3N34GHg6PP4qt2nNan9jDkNQOd22RCcQ88DQBaOjR6EShT48ya2FKIB9bOWi TZulVhLvzAbhv8hVE7kZbesL+ORkY3EQc1UruKPTKlyEO/MmjV3FirFOtAAOPoHbkCYN uYOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=gRIFFRiWtKhehgMZp5r2SWnueOlS4dTgUKCwXFukHZk=; b=tlHWyI4E6zHjnx667fLmO7Nim3GhI+Kk6N+7t9Um11nqplqdYKS/IyOEvHaeFPWfnP clNiAstY9B6VBn5iNPk8uFlzUq8WsSoj4y/Umx1DVMOh6yqrTy0by4lL1iF6VAu5LToe 1/F4FPz6wVws4hb+N7Ch4WHv81gudTOj85doO9CtntwBkQ7jGyZMU92y19t8KNmeUpY0 +yn5cf2jipBPf5cqQfDQ72fLGBbS+5jUlyJIh3DMRNw8srnQLS7lyuvU/MuWrSraLTN1 RujZjzj3qfvIjsP+c/d+LeHGf3ClWWvynzqTweNnOTTfjELYwoRAzlgqmYfJQivduc6F 1Pow== X-Gm-Message-State: AFqh2kpHjEkB3RxVIkGTOI/c3HXBCtVGhof/Bs1bG9wisoOR2o/UZ5N2 wt+f+ixL3GWME8rO8KwHz9kULaOv0fQcxg== X-Received: by 2002:a5d:6104:0:b0:280:cc12:286d with SMTP id v4-20020a5d6104000000b00280cc12286dmr4105974wrt.67.1672207475343; Tue, 27 Dec 2022 22:04:35 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:34 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho , Will Deacon , Peter Zijlstra , Mark Rutland Subject: [PATCH 1/7] rust: sync: add `Arc` for ref-counted allocations Date: Wed, 28 Dec 2022 06:03:40 +0000 Message-Id: <20221228060346.352362-1-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436660353771432?= X-GMAIL-MSGID: =?utf-8?q?1753436660353771432?= This is a basic implementation of `Arc` backed by C's `refcount_t`. It allows Rust code to idiomatically allocate memory that is ref-counted. Cc: Will Deacon Cc: Peter Zijlstra Cc: Boqun Feng Cc: Mark Rutland Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo Acked-by: Boqun Feng --- rust/bindings/bindings_helper.h | 1 + rust/bindings/lib.rs | 1 + rust/helpers.c | 19 ++++ rust/kernel/lib.rs | 1 + rust/kernel/sync.rs | 10 ++ rust/kernel/sync/arc.rs | 157 ++++++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+) create mode 100644 rust/kernel/sync.rs create mode 100644 rust/kernel/sync/arc.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index c48bc284214a..75d85bd6c592 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -7,6 +7,7 @@ */ #include +#include /* `bindgen` gets confused at certain things. */ const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL; diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs index 6c50ee62c56b..7b246454e009 100644 --- a/rust/bindings/lib.rs +++ b/rust/bindings/lib.rs @@ -41,6 +41,7 @@ mod bindings_raw { #[allow(dead_code)] mod bindings_helper { // Import the generated bindings for types. + use super::bindings_raw::*; include!(concat!( env!("OBJTREE"), "/rust/bindings/bindings_helpers_generated.rs" diff --git a/rust/helpers.c b/rust/helpers.c index b4f15eee2ffd..09a4d93f9d62 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -20,6 +20,7 @@ #include #include +#include __noreturn void rust_helper_BUG(void) { @@ -27,6 +28,24 @@ __noreturn void rust_helper_BUG(void) } EXPORT_SYMBOL_GPL(rust_helper_BUG); +refcount_t rust_helper_REFCOUNT_INIT(int n) +{ + return (refcount_t)REFCOUNT_INIT(n); +} +EXPORT_SYMBOL_GPL(rust_helper_REFCOUNT_INIT); + +void rust_helper_refcount_inc(refcount_t *r) +{ + refcount_inc(r); +} +EXPORT_SYMBOL_GPL(rust_helper_refcount_inc); + +bool rust_helper_refcount_dec_and_test(refcount_t *r) +{ + return refcount_dec_and_test(r); +} +EXPORT_SYMBOL_GPL(rust_helper_refcount_dec_and_test); + /* * We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type * as the Rust `usize` type, so we can use it in contexts where Rust diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 53040fa9e897..ace064a3702a 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -31,6 +31,7 @@ mod static_assert; #[doc(hidden)] pub mod std_vendor; pub mod str; +pub mod sync; pub mod types; #[doc(hidden)] diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs new file mode 100644 index 000000000000..39b379dd548f --- /dev/null +++ b/rust/kernel/sync.rs @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Synchronisation primitives. +//! +//! This module contains the kernel APIs related to synchronisation that have been ported or +//! wrapped for usage by Rust code in the kernel. + +mod arc; + +pub use arc::Arc; diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs new file mode 100644 index 000000000000..22290eb5ab9b --- /dev/null +++ b/rust/kernel/sync/arc.rs @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! A reference-counted pointer. +//! +//! This module implements a way for users to create reference-counted objects and pointers to +//! them. Such a pointer automatically increments and decrements the count, and drops the +//! underlying object when it reaches zero. It is also safe to use concurrently from multiple +//! threads. +//! +//! It is different from the standard library's [`Arc`] in a few ways: +//! 1. It is backed by the kernel's `refcount_t` type. +//! 2. It does not support weak references, which allows it to be half the size. +//! 3. It saturates the reference count instead of aborting when it goes over a threshold. +//! 4. It does not provide a `get_mut` method, so the ref counted object is pinned. +//! +//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html + +use crate::{bindings, error::Result, types::Opaque}; +use alloc::boxed::Box; +use core::{marker::PhantomData, ops::Deref, ptr::NonNull}; + +/// A reference-counted pointer to an instance of `T`. +/// +/// The reference count is incremented when new instances of [`Arc`] are created, and decremented +/// when they are dropped. When the count reaches zero, the underlying `T` is also dropped. +/// +/// # Invariants +/// +/// The reference count on an instance of [`Arc`] is always non-zero. +/// The object pointed to by [`Arc`] is always pinned. +/// +/// # Examples +/// +/// ``` +/// use kernel::sync::Arc; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// // Create a ref-counted instance of `Example`. +/// let obj = Arc::try_new(Example { a: 10, b: 20 })?; +/// +/// // Get a new pointer to `obj` and increment the refcount. +/// let cloned = obj.clone(); +/// +/// // Assert that both `obj` and `cloned` point to the same underlying object. +/// assert!(core::ptr::eq(&*obj, &*cloned)); +/// +/// // Destroy `obj` and decrement its refcount. +/// drop(obj); +/// +/// // Check that the values are still accessible through `cloned`. +/// assert_eq!(cloned.a, 10); +/// assert_eq!(cloned.b, 20); +/// +/// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. +/// ``` +pub struct Arc { + ptr: NonNull>, + _p: PhantomData>, +} + +#[repr(C)] +struct ArcInner { + refcount: Opaque, + data: T, +} + +// SAFETY: It is safe to send `Arc` to another thread when the underlying `T` is `Sync` because +// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs +// `T` to be `Send` because any thread that has an `Arc` may ultimately access `T` directly, for +// example, when the reference count reaches zero and `T` is dropped. +unsafe impl Send for Arc {} + +// SAFETY: It is safe to send `&Arc` to another thread when the underlying `T` is `Sync` for the +// same reason as above. `T` needs to be `Send` as well because a thread can clone an `&Arc` +// into an `Arc`, which may lead to `T` being accessed by the same reasoning as above. +unsafe impl Sync for Arc {} + +impl Arc { + /// Constructs a new reference counted instance of `T`. + pub fn try_new(contents: T) -> Result { + // INVARIANT: The refcount is initialised to a non-zero value. + let value = ArcInner { + // SAFETY: There are no safety requirements for this FFI call. + refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), + data: contents, + }; + + let inner = Box::try_new(value)?; + + // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new + // `Arc` object. + Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) + } +} + +impl Arc { + /// Constructs a new [`Arc`] from an existing [`ArcInner`]. + /// + /// # Safety + /// + /// The caller must ensure that `inner` points to a valid location and has a non-zero reference + /// count, one of which will be owned by the new [`Arc`] instance. + unsafe fn from_inner(inner: NonNull>) -> Self { + // INVARIANT: By the safety requirements, the invariants hold. + Arc { + ptr: inner, + _p: PhantomData, + } + } +} + +impl Deref for Arc { + type Target = T; + + fn deref(&self) -> &Self::Target { + // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is + // safe to dereference it. + unsafe { &self.ptr.as_ref().data } + } +} + +impl Clone for Arc { + fn clone(&self) -> Self { + // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero. + // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is + // safe to increment the refcount. + unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) }; + + // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`. + unsafe { Self::from_inner(self.ptr) } + } +} + +impl Drop for Arc { + fn drop(&mut self) { + // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot + // touch `refcount` after it's decremented to a non-zero value because another thread/CPU + // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to + // freed/invalid memory as long as it is never dereferenced. + let refcount = unsafe { self.ptr.as_ref() }.refcount.get(); + + // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and + // this instance is being dropped, so the broken invariant is not observable. + // SAFETY: Also by the type invariant, we are allowed to decrement the refcount. + let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) }; + if is_zero { + // The count reached zero, we must free the memory. + // + // SAFETY: The pointer was initialised from the result of `Box::leak`. + unsafe { Box::from_raw(self.ptr.as_ptr()) }; + } + } +} From patchwork Wed Dec 28 06:03:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37106 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1738488wrt; Tue, 27 Dec 2022 22:05:34 -0800 (PST) X-Google-Smtp-Source: AMrXdXuGZTe/fY25kj1baZXRxiuWrJZ7h2uMwB+eJ3THwXhGdSAGRhhAGcxwcbyUsjeszlpSkO6/ X-Received: by 2002:a05:6a20:e608:b0:9d:efbe:e5f4 with SMTP id my8-20020a056a20e60800b0009defbee5f4mr31361950pzb.16.1672207534074; Tue, 27 Dec 2022 22:05:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207534; cv=none; d=google.com; s=arc-20160816; b=dFAe7Chtim0995bjeSh3PEJZ7eaLMJ+QL8q20xzudXQFab+bLfM5XjX4LqZTpDiWVJ vSki8NBZIFJRudho6C4RTZWWjVu0YIzYmeiFmgGiw9u5A/onZ+FUCvCcOPMrGRV8weJc NaPj5DY96Lcp/JXTwCH9bP+ddPGk0GnldPNarCE0UUGOuylO3O5w+m1Z4d9R66kQVb4B w0SeFdbWKAHP8CcPpdHSQNgnj9vv61v8d8yvKsCRdmVU3x/d+WC/U3OZPNFZhJriZYrp Gl5p1DL97hbMcttpLeemhMFu8hEsdlNzJ1K9k7FuqilB1SLiPfajRaPa40SJ+JLDMrl+ uNHQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=goq/CMrFBd6u+qE+xn52atb3sI7HR978kaW9wQkRdwc=; b=AGiiKMzGhMPoA5nayDir8U+5vlEX0qW9kVJqvjxbKuinW/73lNd/39mNVEPYaMhtbz mQBKD2tpFK0zCHpz2CKsioX4vofZtxMQ4q6FD3p0P1AQVWSCf5ii9HQGMQJMAQt9z783 15wSVkxNgRhSQpwrecVPWA/ahTQ6OA2cXoQuy1zhVPNMn7sLMSyzMahn1uGA+D/wLZ+Z O1AUuZfhhzaBKqJHx3UeQ1Tyc00LZi3NvIKvkzfozwlAVZUym4qhocRw2+bfCV5CdWxt vnoOAv5XGkChuZFW4wdgVMplcoPYX2kAfCbDCAWZ7QF8maEYP2nr/YwynN6rNcXIjMSm Fzzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=QCeu10zR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f2-20020a056a00238200b00576cd9398e7si15822437pfc.1.2022.12.27.22.05.22; Tue, 27 Dec 2022 22:05:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=QCeu10zR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229843AbiL1GEt (ORCPT + 99 others); Wed, 28 Dec 2022 01:04:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229470AbiL1GEj (ORCPT ); Wed, 28 Dec 2022 01:04:39 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A262BDF5E; Tue, 27 Dec 2022 22:04:37 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id n3so13326857wrc.5; Tue, 27 Dec 2022 22:04:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=goq/CMrFBd6u+qE+xn52atb3sI7HR978kaW9wQkRdwc=; b=QCeu10zRclmKJOgwNkQvDbuxs0Cl1FaNUtIhoFH+m++i0zY2pFvcmyZ/f/5JZxDidH Ft52J1m0QnOKBe9gos0xQ9atSJeYrEUe2+qh2Fp08EpdDJnCDERtSlcxk3llQKSXvDVK lG+kW5pfP9UYzhX1ahke286G9Q+OwKDasAeZSK0Kv+ZILmLWOeJkABcUnSqLhNL1x7kD VSbjOkXS6EbpHpzoen1Fg7w3fEaWmtsrKljPhhg5ZVlxbh83TNaZeNBAxwzn+0swy4DN RBWazzkIpzmEqwNK7Eat/8hgHRZwUbmINiXla7hS3ITLAAmfBPf4LVE9ScKqAA8xd0tm vD7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=goq/CMrFBd6u+qE+xn52atb3sI7HR978kaW9wQkRdwc=; b=PtP1a1512jT2ro3nrw4pYr4LSuyXsx/6XEyx7s7SjTvBhC3MdxhiaKXpjw5nN57Ejn XPACBhM79gdGdRg3QxDeZyFjYEfsmprORwbkqOH0Oi+1CpbKUOH89LWYIMkWSJU3oPna XiiF1RKR5GcO4aY56PHkT+VDpnNea9Dm0hbG0YA8cGI8ssua95kDRERqGELQnUTToq08 bU7QgD7OCLQYEDarAHYNu9iXKdEnKAnMgDHHBy2ptK2HZJsCVLcS2fIU3H0PIxiwQJED wmAf9DPTzFdkZN4JvVRlcZUdMIvfKbq51tZdBg9XkOOMVpl2p2F4FmfeIc9iHEiJ3zaV I6gg== X-Gm-Message-State: AFqh2kqPt2ul+faPTFCHc40MdwOmKomNJWkRPenHvXkC+J46HNyIf+Wb dINkgx9humhBAAReSn+OmUBwfvM/HkbtmA== X-Received: by 2002:a5d:430e:0:b0:279:53e1:5178 with SMTP id h14-20020a5d430e000000b0027953e15178mr7260690wrq.45.1672207476141; Tue, 27 Dec 2022 22:04:36 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:35 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 2/7] rust: sync: allow type of `self` to be `Arc` or variants Date: Wed, 28 Dec 2022 06:03:41 +0000 Message-Id: <20221228060346.352362-2-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436687247890915?= X-GMAIL-MSGID: =?utf-8?q?1753436687247890915?= This allows associated functions whose `self` argument has `Arc` or variants as their type. This, in turn, allows callers to use the dot syntax to make calls. Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/lib.rs | 1 + rust/kernel/sync/arc.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index ace064a3702a..1a10f7c0ddd9 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -14,6 +14,7 @@ #![no_std] #![feature(allocator_api)] #![feature(core_ffi_c)] +#![feature(receiver_trait)] // Ensure conditional compilation based on the kernel configuration works; // otherwise we may silently break things like initcall handling. diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 22290eb5ab9b..e2eb0e67d483 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -57,6 +57,31 @@ use core::{marker::PhantomData, ops::Deref, ptr::NonNull}; /// /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. /// ``` +/// +/// Using `Arc` as the type of `self`: +/// +/// ``` +/// use kernel::sync::Arc; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// impl Example { +/// fn take_over(self: Arc) { +/// // ... +/// } +/// +/// fn use_reference(self: &Arc) { +/// // ... +/// } +/// } +/// +/// let obj = Arc::try_new(Example { a: 10, b: 20 })?; +/// obj.use_reference(); +/// obj.take_over(); +/// ``` pub struct Arc { ptr: NonNull>, _p: PhantomData>, @@ -68,6 +93,9 @@ struct ArcInner { data: T, } +// This is to allow [`Arc`] (and variants) to be used as the type of `self`. +impl core::ops::Receiver for Arc {} + // SAFETY: It is safe to send `Arc` to another thread when the underlying `T` is `Sync` because // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs // `T` to be `Send` because any thread that has an `Arc` may ultimately access `T` directly, for From patchwork Wed Dec 28 06:03:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37107 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1738489wrt; Tue, 27 Dec 2022 22:05:34 -0800 (PST) X-Google-Smtp-Source: AMrXdXu/NDxcCfdO9dN4FEgnM3Cg8zRcserYpZkzI1vfTQHUV8KvjS+vC2U54LIrgO9o+uwAO4y7 X-Received: by 2002:a17:90a:fc82:b0:225:d5d1:9023 with SMTP id ci2-20020a17090afc8200b00225d5d19023mr14648966pjb.27.1672207534070; Tue, 27 Dec 2022 22:05:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207534; cv=none; d=google.com; s=arc-20160816; b=Gk7d2OFXBxCM/GEANuU6fvEPCgT1Q083raobiNoADjjRLDteTeg3pyXsigMYz6hnCg 6oMIE+96ru270Aq8Wwi76XL8m/pCspRZM13KgsUT36Vjqt0bUlwmoXxaLIcDdzdjxjlI fM8l4AO+7NPKrrpJ3ienor08abYMi3BCP1Wb+9rd1F2uv60F+GXf8jrypqysXwVBW//T OmwU6rC4qmDmPMgUrg4nKoEqS40XSfhfEUT87aFydU/Lnj1LyFKQNLuEJ31iMkB3tgmd dk9dc/WQqTPi4nmm0KgWBs7embUcrrphk72sBRcXt6peMFNfiURHEWrjHyQbFpfhB7D+ ngJg== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gOo9rRH83QUmkvXUKyYf97kVoLlh2nALRLlTOM81350=; b=kiDsMfOUu4FrRFqEWQXgoy9HdcPfkDimK98p2lYcCKnu3PP80VbQmCJe2TLfXjb0L2 q+VhVtb+RDvST1Ge4SGfV4L3A9cfnbCjMzw77mDFHZVahcZRcPjLl8enDd62sr1pRk+d AUYe1EvsV1seeKpU9pPL2ha6L8ZhdTsRHjIl71iMNXrx4B9X7pgPSTOpB9AJ1R3totCI VNY2qZxBG/6zhnnr01o5/QLW31D2rYpUbdoEqBOGw/vH/G0q7FFr2CIG1KRJOu1KzWyh 9jTU4dVW7kDXw9CeRkNF2z5CL17LT7ZEQvTrvSuuz8pm0QgLGA32gTTr4a0lCiQbxHJj 1MnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Fqd2ghAk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id kb13-20020a17090ae7cd00b0021969656c9esi17259711pjb.3.2022.12.27.22.05.22; Tue, 27 Dec 2022 22:05:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Fqd2ghAk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230018AbiL1GEz (ORCPT + 99 others); Wed, 28 Dec 2022 01:04:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229549AbiL1GEj (ORCPT ); Wed, 28 Dec 2022 01:04:39 -0500 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82481DF7A; Tue, 27 Dec 2022 22:04:38 -0800 (PST) Received: by mail-wr1-x42e.google.com with SMTP id o5so14090668wrm.1; Tue, 27 Dec 2022 22:04:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gOo9rRH83QUmkvXUKyYf97kVoLlh2nALRLlTOM81350=; b=Fqd2ghAkIt63+p69JvueLL8sBn3T/lmXJ/spCefQKbXeohzqEKqM4253s03gDtQ3k2 XDsudlLpPNshviV9YRRttUNpKxSYDumasa2fl7IoDbJ2SkTLyN/3MkRLBC2FlCIjYUWA fr7qu8YNKIRH0Bu6TDFU2T48Bo8rgUBWpQDvSAUhBAQMx9zIiMrC7liYap8mc3RuohUa PabVwkdWPozo3WKJKECyLOt6iAGQ1+MzBe2b5g3JQ3KRLdijDni1YNSAOPJ+Xp2otxUn ld8NfD5yUVKHAalq7VLI603sL+mNE2epnhLgeILZFBh8eAfj5mAJWcKCjfmiX/I7G3cL GtUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gOo9rRH83QUmkvXUKyYf97kVoLlh2nALRLlTOM81350=; b=H2DWKpokXOYGVXMvBfLBUlLvDDp0laCsNZ/R1VySsaf9sIuFRRvcNu2865DydeHMoy 6m94hEvtyMGd0PG+BB9hE60fpwcDZmX6hUn8sZTk9iUkJhHhIQphH3TOYrtA7kG0yckZ 1ok7kZvpAczGZzs4/WtI0eCdekrbAZIk5nX3kKCaZjFjxtQMEWeXQly4k3Ff2lXKeMbE M++Fg+wbGsxYhcaQ20bL1DkKa0fZdYIPkjbJ7pb/EnBVH9svYVLLACIjlK3KMic+pMUb G/voF7cfQvw9sJo1eaRin//EAyIJ2/AUxs9S/JZJPt5il1DMd4Y2KR2QUB9O60QIzw+h aBFw== X-Gm-Message-State: AFqh2kokmtKl0ZuyqXjTT6SQouYpMHhPI+XDlJytTmSj1qySdN9TlmEp h2nI92ZWaJwhsLlkGuAOEr5nrdJK3oLxFg== X-Received: by 2002:adf:e383:0:b0:255:300d:79c7 with SMTP id e3-20020adfe383000000b00255300d79c7mr15597738wrm.18.1672207476964; Tue, 27 Dec 2022 22:04:36 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:36 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 3/7] rust: sync: allow coercion from `Arc` to `Arc` Date: Wed, 28 Dec 2022 06:03:42 +0000 Message-Id: <20221228060346.352362-3-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436686975330166?= X-GMAIL-MSGID: =?utf-8?q?1753436686975330166?= The coercion is only allowed if `U` is a compatible dynamically-sized type (DST). For example, if we have some type `X` that implements trait `Y`, then this allows `Arc` to be coerced into `Arc`. Suggested-by: Gary Guo Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/lib.rs | 2 ++ rust/kernel/sync/arc.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 1a10f7c0ddd9..4bde65e7b06b 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -13,8 +13,10 @@ #![no_std] #![feature(allocator_api)] +#![feature(coerce_unsized)] #![feature(core_ffi_c)] #![feature(receiver_trait)] +#![feature(unsize)] // Ensure conditional compilation based on the kernel configuration works; // otherwise we may silently break things like initcall handling. diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index e2eb0e67d483..dbc7596cc3ce 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -17,7 +17,11 @@ use crate::{bindings, error::Result, types::Opaque}; use alloc::boxed::Box; -use core::{marker::PhantomData, ops::Deref, ptr::NonNull}; +use core::{ + marker::{PhantomData, Unsize}, + ops::Deref, + ptr::NonNull, +}; /// A reference-counted pointer to an instance of `T`. /// @@ -82,6 +86,23 @@ use core::{marker::PhantomData, ops::Deref, ptr::NonNull}; /// obj.use_reference(); /// obj.take_over(); /// ``` +/// +/// Coercion from `Arc` to `Arc`: +/// +/// ``` +/// use kernel::sync::Arc; +/// +/// trait MyTrait {} +/// +/// struct Example; +/// impl MyTrait for Example {} +/// +/// // `obj` has type `Arc`. +/// let obj: Arc = Arc::try_new(Example)?; +/// +/// // `coerced` has type `Arc`. +/// let coerced: Arc = obj; +/// ``` pub struct Arc { ptr: NonNull>, _p: PhantomData>, @@ -96,6 +117,10 @@ struct ArcInner { // This is to allow [`Arc`] (and variants) to be used as the type of `self`. impl core::ops::Receiver for Arc {} +// This is to allow coercion from `Arc` to `Arc` if `T` can be converted to the +// dynamically-sized type (DST) `U`. +impl, U: ?Sized> core::ops::CoerceUnsized> for Arc {} + // SAFETY: It is safe to send `Arc` to another thread when the underlying `T` is `Sync` because // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs // `T` to be `Send` because any thread that has an `Arc` may ultimately access `T` directly, for From patchwork Wed Dec 28 06:03:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37108 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1738539wrt; Tue, 27 Dec 2022 22:05:46 -0800 (PST) X-Google-Smtp-Source: AMrXdXvSI6MI+4T6D+nZxFIfps027bYJ0pyJy3fp9XAv2cAksEWK3TXDt6cIRiIPxK2qOlDks58I X-Received: by 2002:a17:90b:485:b0:223:ffd0:b2a1 with SMTP id bh5-20020a17090b048500b00223ffd0b2a1mr27532378pjb.48.1672207545997; Tue, 27 Dec 2022 22:05:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207545; cv=none; d=google.com; s=arc-20160816; b=kkaghssERIXf0VcY8Fo3dnyCdJhLWp6yxNWf4iVEMSc9oG+RF7QmlUL9YpFrm4G0ol vPc8DAyTyaJFzFgu1olAu9LxyRQdmeLQXKmFRFCSFNeayZ4cqYzxSzhrM9/Nkt0nSU4s VrGHw79eRR2pNzV6AT5Q2RF5dHYBC/0D/78V4t+2PrCUr5icVuHsgmJfogSgWCfx030Q mp4nUp5BG1eMh+f1Yw4phXKyHJ1YGjGDxUheL9YhjAV5t41vCp2PzwunrSOlokkLVrOZ zQ+8R4fjYfZK6bn7GrdOx/pjbNF/liXpxFKtae03kgo+NTUWcDpxcj9LmLG66pj5/UjY NEtw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=NYJ20jftMQ92CUxnJjaaHKdOk3jkOftLaji4+9En0dc=; b=q+D8R7MJHY82m7Zp3m9QSiykhgG0/9T/9drbPJhDv6nOjL2QCpasj7QsJO5A0ZQsp0 P4cX3YrwV14Dam8tK5x5v9bc/BKmYsTOc2VaSBWMaoC5+Vcjw6tvS4NQF48KnyP9GDqM TpYxGx/KqkQn9M15s5d0RLd0IrL/ekBOlrtGoiFyjKyfGj4Q4ThXw00b/o3V5xbZ/2LV 04/OyvMxz2qmI6q5UheT9ZeuXHlEsRX/1IcueAOCQ2t9QfNSbR9uAAeB5P7Tg0gheEmY MXr730tfeUYrJh6il13UoCxl1sTlsOG4w1vdM/sintPKvhf3l4bh15a1BBeP/SS32NnE jwQA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=igz9ApMN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id on16-20020a17090b1d1000b00225b427da47si18445539pjb.51.2022.12.27.22.05.34; Tue, 27 Dec 2022 22:05:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=igz9ApMN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230136AbiL1GE6 (ORCPT + 99 others); Wed, 28 Dec 2022 01:04:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229583AbiL1GEk (ORCPT ); Wed, 28 Dec 2022 01:04:40 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73CBADFAE; Tue, 27 Dec 2022 22:04:39 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id n3so13326896wrc.5; Tue, 27 Dec 2022 22:04:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NYJ20jftMQ92CUxnJjaaHKdOk3jkOftLaji4+9En0dc=; b=igz9ApMN93MMMvir8cEZVLhAlEwrT5qCIUt8GTeIg9hE1k033dQeVJAxv9ZNQC/TH4 mSJAMfWRk/P9OLtuX+1Xzbu0cA9hRzElS+i3j2cKO6fbY9xrfflj5Rmno/aV/LRQCak5 QLAw9IWaJ4lRtxWb1kKH/CQ+sJA7yJerLb8ueS3HajQYmSbeHObV9r+oiVt0tflpvPdy /A9LXfLy5OqkMF6JzMfRU8uL1yIFStcEziBi6wGqQl3DPpZhOXLVtDCIP8unUXpxCGOq uDwEUjf/jV1O4xC5JKbHoPFHjVEz/osPp5nWrWohUBBjLKoZDyDeFALPR/Jsvnby3tTH 5u9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NYJ20jftMQ92CUxnJjaaHKdOk3jkOftLaji4+9En0dc=; b=3M6/tmOQn6FIQOhT5VDXEOw9PeHIMaTIubIKzTD2pKeFK3FVqXJb2fd5rrn+btC4Q1 T7P/+JNiiofomIx+mNRVyAEvsgyLQzWiE2mIyIS7L4bpjntJq/5Utc5GjhDyo6RVe/bc t/desAQSTSqC+Q2QmsTFLii0z8MI1B+23C7PAFVhfrrNLu1gDoUamiWkU01HmA8cIYTF rNf/PuMTQ/eH1AFtQxc+sTIL22bnKX1/PFHA0pQbrvhTKP+nEthE55jB3Ez2jvSkKmqf T/WIzebdGegwCR8/J9xxuiGDJsYUp9xqfEdIxtTWxYHbFObbHh8CmzuY6Ps2E1vr6rXK eUbg== X-Gm-Message-State: AFqh2kqidosWGstyblvHRkVf20XWJiFrbDWGYIyQyxPoyRa/2ZsWwthU oyjgsyJXNcjucLNkFUIPyvQdsMdp6rGlaA== X-Received: by 2002:adf:ec4f:0:b0:27b:a73e:33ae with SMTP id w15-20020adfec4f000000b0027ba73e33aemr6257770wrn.8.1672207477843; Tue, 27 Dec 2022 22:04:37 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:37 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 4/7] rust: sync: introduce `ArcBorrow` Date: Wed, 28 Dec 2022 06:03:43 +0000 Message-Id: <20221228060346.352362-4-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436699680110267?= X-GMAIL-MSGID: =?utf-8?q?1753436699680110267?= This allows us to create references to a ref-counted allocation without double-indirection and that still allow us to increment the refcount to a new `Arc`. Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/sync.rs | 2 +- rust/kernel/sync/arc.rs | 97 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs index 39b379dd548f..5de03ea83ea1 100644 --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -7,4 +7,4 @@ mod arc; -pub use arc::Arc; +pub use arc::{Arc, ArcBorrow}; diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index dbc7596cc3ce..f68bfc02c81a 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -19,6 +19,7 @@ use crate::{bindings, error::Result, types::Opaque}; use alloc::boxed::Box; use core::{ marker::{PhantomData, Unsize}, + mem::ManuallyDrop, ops::Deref, ptr::NonNull, }; @@ -164,6 +165,18 @@ impl Arc { _p: PhantomData, } } + + /// Returns an [`ArcBorrow`] from the given [`Arc`]. + /// + /// This is useful when the argument of a function call is an [`ArcBorrow`] (e.g., in a method + /// receiver), but we have an [`Arc`] instead. Getting an [`ArcBorrow`] is free when optimised. + #[inline] + pub fn as_arc_borrow(&self) -> ArcBorrow<'_, T> { + // SAFETY: The constraint that the lifetime of the shared reference must outlive that of + // the returned `ArcBorrow` ensures that the object remains alive and that no mutable + // reference can be created. + unsafe { ArcBorrow::new(self.ptr) } + } } impl Deref for Arc { @@ -208,3 +221,87 @@ impl Drop for Arc { } } } + +/// A borrowed reference to an [`Arc`] instance. +/// +/// For cases when one doesn't ever need to increment the refcount on the allocation, it is simpler +/// to use just `&T`, which we can trivially get from an `Arc` instance. +/// +/// However, when one may need to increment the refcount, it is preferable to use an `ArcBorrow` +/// over `&Arc` because the latter results in a double-indirection: a pointer (shared reference) +/// to a pointer (`Arc`) to the object (`T`). An [`ArcBorrow`] eliminates this double +/// indirection while still allowing one to increment the refcount and getting an `Arc` when/if +/// needed. +/// +/// # Invariants +/// +/// There are no mutable references to the underlying [`Arc`], and it remains valid for the +/// lifetime of the [`ArcBorrow`] instance. +/// +/// # Example +/// +/// ``` +/// use crate::sync::{Arc, ArcBorrow}; +/// +/// struct Example; +/// +/// fn do_something(e: ArcBorrow<'_, Example>) -> Arc { +/// e.into() +/// } +/// +/// let obj = Arc::try_new(Example)?; +/// let cloned = do_something(obj.as_arc_borrow()); +/// +/// // Assert that both `obj` and `cloned` point to the same underlying object. +/// assert!(core::ptr::eq(&*obj, &*cloned)); +/// ``` +pub struct ArcBorrow<'a, T: ?Sized + 'a> { + inner: NonNull>, + _p: PhantomData<&'a ()>, +} + +impl Clone for ArcBorrow<'_, T> { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for ArcBorrow<'_, T> {} + +impl ArcBorrow<'_, T> { + /// Creates a new [`ArcBorrow`] instance. + /// + /// # Safety + /// + /// Callers must ensure the following for the lifetime of the returned [`ArcBorrow`] instance: + /// 1. That `inner` remains valid; + /// 2. That no mutable references to `inner` are created. + unsafe fn new(inner: NonNull>) -> Self { + // INVARIANT: The safety requirements guarantee the invariants. + Self { + inner, + _p: PhantomData, + } + } +} + +impl From> for Arc { + fn from(b: ArcBorrow<'_, T>) -> Self { + // SAFETY: The existence of `b` guarantees that the refcount is non-zero. `ManuallyDrop` + // guarantees that `drop` isn't called, so it's ok that the temporary `Arc` doesn't own the + // increment. + ManuallyDrop::new(unsafe { Arc::from_inner(b.inner) }) + .deref() + .clone() + } +} + +impl Deref for ArcBorrow<'_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + // SAFETY: By the type invariant, the underlying object is still alive with no mutable + // references to it, so it is safe to create a shared reference. + unsafe { &self.inner.as_ref().data } + } +} From patchwork Wed Dec 28 06:03:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37109 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1738917wrt; Tue, 27 Dec 2022 22:06:57 -0800 (PST) X-Google-Smtp-Source: AMrXdXvlcM6Oy7+UlUscWUVuHuIlEPGLM4bimLyLHkKp9zkWTniCef8Ujv7ZXEg5KqUGzj3pbZ8R X-Received: by 2002:a05:6402:4503:b0:472:d867:4c3d with SMTP id ez3-20020a056402450300b00472d8674c3dmr24635908edb.40.1672207617320; Tue, 27 Dec 2022 22:06:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207617; cv=none; d=google.com; s=arc-20160816; b=L/ZyLe35vbI5T4MPotVAlIabYaf6PbOPnOAaMxJu8jFplS4ov1W5MT1i44SB67A6ih CeclAo8CjVLc7QcNcN7v4rAIpGrvMdS0lE0yB0B98mQ4ZbCKaaCOh+j/p0Mw9ctSiOTV R7Ja7PPA44Sn5NIDw1hTWWiwloF/qK7dyOB9miaA8NAzg7tAKVGcDoNweZlUtADyXaHI qC5R5rnFcH9uH17OzJhq476SEC1FN63DgrBnqWDSeFFUNOJfKQAKxYw7j92f1EKUH2X7 xpVB0eqnL/iCzvG44wYFJ5MVn4i/enVolVmgSD9ZCHCjeGsEeISYJRkxXERwLWbpmnBl xWcw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=XeNZhBrSDUYQju7RRVfm5I6e0SpSr4tjimgdJCI7t2s=; b=uR8NgCjdlRydf79Fy5GR42nppfKbNIFMCPpre/C/h786+DBTgf1d+9uFnQp6W0zA5Q occsnPTiAt/EUechIiGWhZscMewB8RaQzz/S8daH6ZnWxCJiE3/rpWhcH+4xh8Jjqd7k pH7uCZchhao/hfnXAgjJVFNXh6CmocF5fP5sdt9xeDNJ8hMxGS3LeVtYEjcW22bWuklO DVPFBWCxkoZe8XC9JwEl6MW4fmeJRXsn8P7CcFy2J0rORPF2JskdEWjyRlLgh90H9TQn OFCbazO1cLOpP46/U8JVIC9L2QATXVy+CNUiAZClgHZQiosZbFN0K+vPNYu9PNHWTvQk izeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=hBpEZlcw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z11-20020a05640240cb00b004683b475587si13767381edb.274.2022.12.27.22.06.33; Tue, 27 Dec 2022 22:06:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=hBpEZlcw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230273AbiL1GFC (ORCPT + 99 others); Wed, 28 Dec 2022 01:05:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229608AbiL1GEl (ORCPT ); Wed, 28 Dec 2022 01:04:41 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E31BDEFD; Tue, 27 Dec 2022 22:04:40 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id y16so14086160wrm.2; Tue, 27 Dec 2022 22:04:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XeNZhBrSDUYQju7RRVfm5I6e0SpSr4tjimgdJCI7t2s=; b=hBpEZlcwkbj1rwV3hPjKwJmJHcE/5WKwhuxtTDMKYQKe2CImcnt3QdOTvLb7G7vEY4 cqAMRxB0qP5ptsaD8CH/fdev6J9lAFCvaVf+rkbnKb7QQSMFbGhBoXvof6zYHSe8i9j4 Ej6C+CnpjBTVmgO+yLnO1BwCIJEA/QrKu68BwcgCie7xHBAEqJBwibjX8YKWNOXLHgQq BxLIxnbEoBGpzK3vookEkJwtNUMwU5XAXlF131X5LqUOo2qEQR4lZP6Pk4GkvuYwdSMg vkAuHPsze27Lso5+WNQEWsAtgOn9PrShtaONkq/3X8N+O1r4VT03bbewoxFg7FTAnH0d ZNOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XeNZhBrSDUYQju7RRVfm5I6e0SpSr4tjimgdJCI7t2s=; b=1ZevucE/i31PSMP2Z1j6C1qkrW3aXXg/zefLhH9fst0F2y42vPTbKWJMfappZ6aVrs oGYRp6NtOrC1+7bcIn93huTS8QKIdiYJqAdsW7faS8A6V3/GbhacuRirnrnexWMZg+l0 zoYDOmrTv/9Ei5+awxblfaLOU/H9N4wPcl9nQv0GYweI2q87fHaOcw0roDWQVF5HPb+5 +9ZVSQHYfX958JifpwIDUW8wobKKdvsWlGvqSC4CmJV9XNy/+/y5oIKBI2j4vrXvSWA3 HkPd/DIi3BS5d+odnItntycyNzNTP+rPuvOFnC0GgzW2IL+FpcEartq8kllTBpFqa3Zi Kqqg== X-Gm-Message-State: AFqh2ko9xXpHDVv8FqWJfD41v3d0DfKp0m75/vc0OdOXpWCa5M7UnQZJ OiqEP9NO6pxeK4xyue11Sfcw6rdujSaq7Q== X-Received: by 2002:adf:f206:0:b0:280:8ebd:263a with SMTP id p6-20020adff206000000b002808ebd263amr4491556wro.62.1672207478627; Tue, 27 Dec 2022 22:04:38 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:38 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 5/7] rust: sync: allow type of `self` to be `ArcBorrow` Date: Wed, 28 Dec 2022 06:03:44 +0000 Message-Id: <20221228060346.352362-5-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436774409897158?= X-GMAIL-MSGID: =?utf-8?q?1753436774409897158?= This allows associated functions whose `self` argument has `ArcBorrow` as their type. This, in turn, allows callers to use the dot syntax to make calls. Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/sync/arc.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index f68bfc02c81a..84f31c85a513 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -255,11 +255,34 @@ impl Drop for Arc { /// // Assert that both `obj` and `cloned` point to the same underlying object. /// assert!(core::ptr::eq(&*obj, &*cloned)); /// ``` +/// +/// Using `ArcBorrow` as the type of `self`: +/// +/// ``` +/// use crate::sync::{Arc, ArcBorrow}; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// impl Example { +/// fn use_reference(self: ArcBorrow<'_, Self>) { +/// // ... +/// } +/// } +/// +/// let obj = Arc::try_new(Example { a: 10, b: 20 })?; +/// obj.as_arc_borrow().use_reference(); +/// ``` pub struct ArcBorrow<'a, T: ?Sized + 'a> { inner: NonNull>, _p: PhantomData<&'a ()>, } +// This is to allow [`ArcBorrow`] (and variants) to be used as the type of `self`. +impl core::ops::Receiver for ArcBorrow<'_, T> {} + impl Clone for ArcBorrow<'_, T> { fn clone(&self) -> Self { *self From patchwork Wed Dec 28 06:03:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37112 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1739576wrt; Tue, 27 Dec 2022 22:09:16 -0800 (PST) X-Google-Smtp-Source: AMrXdXvgrDdUogGaSdzxMpOyZzjDDgC65eToq6RZE8rVZHoUMVH86WLwD6TIcltAW81IrLKPVlHb X-Received: by 2002:a17:90a:6c22:b0:220:987d:d28a with SMTP id x31-20020a17090a6c2200b00220987dd28amr27024228pjj.47.1672207755782; Tue, 27 Dec 2022 22:09:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207755; cv=none; d=google.com; s=arc-20160816; b=z9V37hOSIZQ5BD84pnXv+qoWVQ64/ZUcO9oJlA+aaJpShe48C8eFFwHSMgljN+Sh/M ja1LKVwDosjiOyCSgLbGovgswZODXzxqNmiyID64dtv1K0vX5HCBBI3QBg8KLHwspisB Zpg39e/K+qWZjChr5CLdiD0D2Xp0nIjWFjny6UaEBskXliTSdsXQcjJroaZ1xz8T56Cj 9XSfnlPRyUwxci9dUFD9k8NF2MB9FyvxDf2ke9LKP2rocgn8QWDaJEAASphMbRVhg0c5 fQv2spv70vr90VTaw7JNHAKbDfGaDQl78BmZE066Ynl+vok21UvtClfqlKv78lzplusU ecYQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=s76JV/Exvx+RM2maTBqxn8/tfygp8gqzjmIPH1TmhL4=; b=K7SRZlmD2DLBdLvPtfa/I506J9kasH5F0VAHQ2YzBtoY/0nC+tt3iBYu35PKNHXCmE rgHd4IUQ1QeV0C6fl3ON98f/kGXJW5kDIgGrpekh0xWZ6EhPjsp89GULyYmjR0Co03To +XejTP4WP55THjZiKjMTdQKSFURn+Lo6k68snPm9dhR19MubVHAATWJ23P22kq+NQP3m EkAU4MinZbyvjfdXo7p+4EyGV6+mLqtCMKHujN64AOrclRuVnZlhegwUdp1gas57zLeJ YfxCot2wDN2W/gW4l+LhPSZWfhnvdLaNu1comLCOTENqFvPdd9CULCR9LtRqVGdHQWGf sXTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=ZRxl3nUZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w64-20020a638243000000b004960837e38csi15808861pgd.37.2022.12.27.22.09.04; Tue, 27 Dec 2022 22:09:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=ZRxl3nUZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231533AbiL1GFF (ORCPT + 99 others); Wed, 28 Dec 2022 01:05:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229494AbiL1GEm (ORCPT ); Wed, 28 Dec 2022 01:04:42 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 185FEDF1B; Tue, 27 Dec 2022 22:04:41 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id bx10so14105631wrb.0; Tue, 27 Dec 2022 22:04:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s76JV/Exvx+RM2maTBqxn8/tfygp8gqzjmIPH1TmhL4=; b=ZRxl3nUZob8rBBEhsqXnWL0rXlFlstDxouDNrtu7aJYWnNEUFtG6Azp9erA4Y4alPC XSu+SYDAGGkDQ49yjn+eFmOiN1oadkbrhc86SbsqxCMwrlG6Uv+D1ti2w3qeqDUM74kn OFoTBsiuX9oAqA1QqdMrRAleoiGb6Nso0ar+AoyNXlPCt9QC9mbo3bTHYuEBRo7okWpX KSCZIDSs29WNd8wLBwOB11u9kNlqqnL06hoY6PGhbmJA8Kc8ovJRDKgkfM/wwC14jgTM ZYvaPuz5aOX0jNhXjqsex1rQlS+RH2841sAislzO3z4nQoQ/Xh8uvQa5z7PV1sW/5mbk NC1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s76JV/Exvx+RM2maTBqxn8/tfygp8gqzjmIPH1TmhL4=; b=wMArZmZ7fkFGnRod/2+dOjg9ujfsaf/87APvYN3XDQL0Nu065u9Y0bLW77JV05jGOn J5dRN9Rcp6IIaoKR0S0H5c36IGJx70yD5DguGq2Q0cUuzsI+18X2WcrR47PTG0JLSz2K QIPDMOFq6ABpsh2ooCDf4yigACbjyFZqvSg+0USQ0rABanjQKdiHvl4pdwlX6oIwt4wC PFRhokhwjjuKQCl/koS2puscvzEuFxXAGFA7b68CxWcoAQGrKOjvvmtv4ny97RQKXlsR bOQE8LECaqDTu+fcz49hW0Dw1VVoRnKIPx6MpZFsZIpFb2yMdDow3qO7X3sGOs/JX+7g 7fAg== X-Gm-Message-State: AFqh2ko+2EOd7BPNZ2nOzaSSYb7zB5kZG6vHk1Ehb2gQm463r21fv+Aa hw8cKyJ+h8M1jUV0eiUXbMFZon3HY0WeCA== X-Received: by 2002:a05:6000:1801:b0:242:1f22:df11 with SMTP id m1-20020a056000180100b002421f22df11mr15566170wrh.4.1672207479545; Tue, 27 Dec 2022 22:04:39 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:39 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 6/7] rust: sync: introduce `UniqueArc` Date: Wed, 28 Dec 2022 06:03:45 +0000 Message-Id: <20221228060346.352362-6-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436919446231430?= X-GMAIL-MSGID: =?utf-8?q?1753436919446231430?= Since `Arc` does not allow mutating `T` directly (i.e., without inner mutability), it is currently not possible to do some initialisation of `T` post construction but before being shared. `UniqueArc` addresses this problem essentially being an `Arc` that has a refcount of 1 and is therefore writable. Once initialisation is completed, it can be transitioned (without failure paths) into an `Arc`. Suggested-by: Gary Guo Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/sync.rs | 2 +- rust/kernel/sync/arc.rs | 152 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 3 deletions(-) diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs index 5de03ea83ea1..33da23e3076d 100644 --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -7,4 +7,4 @@ mod arc; -pub use arc::{Arc, ArcBorrow}; +pub use arc::{Arc, ArcBorrow, UniqueArc}; diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 84f31c85a513..832bafc74a90 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -19,8 +19,9 @@ use crate::{bindings, error::Result, types::Opaque}; use alloc::boxed::Box; use core::{ marker::{PhantomData, Unsize}, - mem::ManuallyDrop, - ops::Deref, + mem::{ManuallyDrop, MaybeUninit}, + ops::{Deref, DerefMut}, + pin::Pin, ptr::NonNull, }; @@ -222,6 +223,19 @@ impl Drop for Arc { } } +impl From> for Arc { + fn from(item: UniqueArc) -> Self { + item.inner + } +} + +impl From>> for Arc { + fn from(item: Pin>) -> Self { + // SAFETY: The type invariants of `Arc` guarantee that the data is pinned. + unsafe { Pin::into_inner_unchecked(item).inner } + } +} + /// A borrowed reference to an [`Arc`] instance. /// /// For cases when one doesn't ever need to increment the refcount on the allocation, it is simpler @@ -328,3 +342,137 @@ impl Deref for ArcBorrow<'_, T> { unsafe { &self.inner.as_ref().data } } } + +/// A refcounted object that is known to have a refcount of 1. +/// +/// It is mutable and can be converted to an [`Arc`] so that it can be shared. +/// +/// # Invariants +/// +/// `inner` always has a reference count of 1. +/// +/// # Examples +/// +/// In the following example, we make changes to the inner object before turning it into an +/// `Arc` object (after which point, it cannot be mutated directly). Note that `x.into()` +/// cannot fail. +/// +/// ``` +/// use kernel::sync::{Arc, UniqueArc}; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// fn test() -> Result> { +/// let mut x = UniqueArc::try_new(Example { a: 10, b: 20 })?; +/// x.a += 1; +/// x.b += 1; +/// Ok(x.into()) +/// } +/// +/// # test().unwrap(); +/// ``` +/// +/// In the following example we first allocate memory for a ref-counted `Example` but we don't +/// initialise it on allocation. We do initialise it later with a call to [`UniqueArc::write`], +/// followed by a conversion to `Arc`. This is particularly useful when allocation happens +/// in one context (e.g., sleepable) and initialisation in another (e.g., atomic): +/// +/// ``` +/// use kernel::sync::{Arc, UniqueArc}; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// fn test() -> Result> { +/// let x = UniqueArc::try_new_uninit()?; +/// Ok(x.write(Example { a: 10, b: 20 }).into()) +/// } +/// +/// # test().unwrap(); +/// ``` +/// +/// In the last example below, the caller gets a pinned instance of `Example` while converting to +/// `Arc`; this is useful in scenarios where one needs a pinned reference during +/// initialisation, for example, when initialising fields that are wrapped in locks. +/// +/// ``` +/// use kernel::sync::{Arc, UniqueArc}; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// fn test() -> Result> { +/// let mut pinned = Pin::from(UniqueArc::try_new(Example { a: 10, b: 20 })?); +/// // We can modify `pinned` because it is `Unpin`. +/// pinned.as_mut().a += 1; +/// Ok(pinned.into()) +/// } +/// +/// # test().unwrap(); +/// ``` +pub struct UniqueArc { + inner: Arc, +} + +impl UniqueArc { + /// Tries to allocate a new [`UniqueArc`] instance. + pub fn try_new(value: T) -> Result { + Ok(Self { + // INVARIANT: The newly-created object has a ref-count of 1. + inner: Arc::try_new(value)?, + }) + } + + /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet. + pub fn try_new_uninit() -> Result>> { + Ok(UniqueArc::> { + // INVARIANT: The newly-created object has a ref-count of 1. + inner: Arc::try_new(MaybeUninit::uninit())?, + }) + } +} + +impl UniqueArc> { + /// Converts a `UniqueArc>` into a `UniqueArc` by writing a value into it. + pub fn write(mut self, value: T) -> UniqueArc { + self.deref_mut().write(value); + let inner = ManuallyDrop::new(self).inner.ptr; + UniqueArc { + // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be + // dropped). The types are compatible because `MaybeUninit` is compatible with `T`. + inner: unsafe { Arc::from_inner(inner.cast()) }, + } + } +} + +impl From> for Pin> { + fn from(obj: UniqueArc) -> Self { + // SAFETY: It is not possible to move/replace `T` inside a `Pin>` (unless `T` + // is `Unpin`), so it is ok to convert it to `Pin>`. + unsafe { Pin::new_unchecked(obj) } + } +} + +impl Deref for UniqueArc { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.inner.deref() + } +} + +impl DerefMut for UniqueArc { + fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: By the `Arc` type invariant, there is necessarily a reference to the object, so + // it is safe to dereference it. Additionally, we know there is only one reference when + // it's inside a `UniqueArc`, so it is safe to get a mutable reference. + unsafe { &mut self.inner.ptr.as_mut().data } + } +} From patchwork Wed Dec 28 06:03:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wedson Almeida Filho X-Patchwork-Id: 37110 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1739280wrt; Tue, 27 Dec 2022 22:08:12 -0800 (PST) X-Google-Smtp-Source: AMrXdXsAcc1K9tYKum2W9H9wz0ahjeMB063/4HhcxJG6H75XFSKUCfFuWyQHxxjclUv0kVOtJz3Z X-Received: by 2002:a17:902:7805:b0:191:bb:c207 with SMTP id p5-20020a170902780500b0019100bbc207mr23813791pll.37.1672207692083; Tue, 27 Dec 2022 22:08:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672207692; cv=none; d=google.com; s=arc-20160816; b=eam42zGW5IN2MJ6IyeFg8+XuFBYKL4lMtxHcRc0n0Eki0wuC9PGPIEaRZeHmK/pd23 Kkt2AgdZNsDvxxPd8x6pzTjZ6nuYlpHqJ1dvrGDuxax9HVrxmEEgL1B38P7cebIA/Hlz g61mzBTGtIqwW95SUuQPA2I0AA9uurOCIXb4Q/qP0G3mzRSLp6uf984BhXfBe5mP9Gk2 tT8HQmt5zXrX/0J/jPqT9BJyscVCBZhsPmOCAdPboG3I64gmdcPijzvGMjQjzU1biJaq YRKCd8Da5JEdmqV+KSh84LGWea15VP7zMksOa5aR0l0NttIzSYLgs5s8C2BHk6e0YMT1 1DCw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Nyqdaq2S7tC0O5h+EPr9voswYlNOiiQ62YOgK8u+XEY=; b=GZbeLd3QpCCx5cLA8NUQrhaR6F8zHtX+wWkAvJbQEcwbrctSQiRscmTfviyOlnmO+u uUwK8zUjUZAn/jZVGmZfijHw8jg+kgxDSK2uIZEayeDAa4MFtCf6uMST2rzJoSfan9bc gGvwZA5K9BolrZ53BUvtakLGgYLyTVtQO9Q48HPx6ygFGoDC4oPspcVHYcvnqXy6dVbz HddD8yuwYFP5w1rMVfbaSinHTyrxwex5IaM+iZ9i/DdHEAb796PtWq3BxzMDfycVmrqT OmkSoTY9+Xo7CacvPdT96EYbYduvqZlTVVe+dlrBBQK1sWuBCACjFda+OTr5vYpiravm l9gQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=PkjOU0Ow; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o17-20020a170902d4d100b0018701f083b1si17381623plg.619.2022.12.27.22.07.59; Tue, 27 Dec 2022 22:08:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=PkjOU0Ow; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232272AbiL1GFJ (ORCPT + 99 others); Wed, 28 Dec 2022 01:05:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229666AbiL1GEn (ORCPT ); Wed, 28 Dec 2022 01:04:43 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 054C7DF5E; Tue, 27 Dec 2022 22:04:42 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id t15so5238847wro.9; Tue, 27 Dec 2022 22:04:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Nyqdaq2S7tC0O5h+EPr9voswYlNOiiQ62YOgK8u+XEY=; b=PkjOU0OwjgOja8a24OYSeB2xiCXsUcXR2DuCf4HwLICZZ6x5sUmJcWD+n6ZDvBAkTG Q+yDtygd9skAsH7t4D3HxYgI4yhnyQ4mSJt1uW+qYKr5q7Jka2QoKZll1mkxK5Ug149F fO1lUz8ciMe3jG1z4R/He3IGT7X3d09qLVq8L5fdAc+sQv1qBijTYeekmQUnBnE0KJ6y ZxPStzKKAtcEnK1FxUL6vlmqE8oH/vjbQ/iiV0qSrloeoFwlXy3KIVD5QWoGxMAmG4OW y+g3SztzbfqSiPuTK8NIqTg6b99rR+6POIH9XoXMkEZ0Bwj5wbv5fnr8W/bbql43LwpJ +Rug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Nyqdaq2S7tC0O5h+EPr9voswYlNOiiQ62YOgK8u+XEY=; b=onRpjMBBF4HRqEBlmSaNibzSz7COsuAPjn+8KM/7duv2V2aavRDQECpwzr6uPAzMNQ m3OZyoq7nycNz/UiFdYeowxLhvfSb1Wd8qqdhCXPKmKqjFzf685KfVbFIqgyPDRM6utX R4pHfEZn0GPaB8grdVV5/uPklAjPU10qmJj9XCW22Y4liAdHprwfqCuWwmwoSgdURuCB FlII50Eo2L3nOHTDdygMz8S7rkIq2yAd5+cV2tc7zmpOq3cb9IdzSy4j3HdqJgq65OAA oz7heN+OuIBa4utdlA5mkR83P3ezlnJkM0f5tfqOGjUUbdYtyRYae/oHglQfZID29nXu 4L9Q== X-Gm-Message-State: AFqh2kqRX257t2wXcArj2++vzM0+giWLTY7WdBn7Yvbfd+iJdT/eBr7a ItkRxr2I9glTjWUeo2iDBku8dZ86FpwEHA== X-Received: by 2002:a5d:494d:0:b0:268:5557:98c9 with SMTP id r13-20020a5d494d000000b00268555798c9mr14607418wrs.58.1672207480519; Tue, 27 Dec 2022 22:04:40 -0800 (PST) Received: from wedsonaf-dev.. ([81.2.152.129]) by smtp.googlemail.com with ESMTPSA id x16-20020a5d6510000000b002755e301eeasm12128867wru.100.2022.12.27.22.04.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Dec 2022 22:04:40 -0800 (PST) From: Wedson Almeida Filho To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?B?= =?utf-8?q?j=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, Wedson Almeida Filho Subject: [PATCH 7/7] rust: sync: add support for dispatching on Arc and ArcBorrow. Date: Wed, 28 Dec 2022 06:03:46 +0000 Message-Id: <20221228060346.352362-7-wedsonaf@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221228060346.352362-1-wedsonaf@gmail.com> References: <20221228060346.352362-1-wedsonaf@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753436852714896144?= X-GMAIL-MSGID: =?utf-8?q?1753436852714896144?= Trait objects (`dyn T`) require trait `T` to be "object safe". One of the requirements for "object safety" is that the receiver have one of the allowed types. This commit adds `Arc` and `ArcBorrow<'_, T>` to the list of allowed types. Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo --- rust/kernel/lib.rs | 1 + rust/kernel/sync/arc.rs | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 4bde65e7b06b..e0b0e953907d 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -15,6 +15,7 @@ #![feature(allocator_api)] #![feature(coerce_unsized)] #![feature(core_ffi_c)] +#![feature(dispatch_from_dyn)] #![feature(receiver_trait)] #![feature(unsize)] diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 832bafc74a90..ff73f9240ca1 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -92,9 +92,15 @@ use core::{ /// Coercion from `Arc` to `Arc`: /// /// ``` -/// use kernel::sync::Arc; +/// use kernel::sync::{Arc, ArcBorrow}; +/// +/// trait MyTrait { +/// // Trait has a function whose `self` type is `Arc`. +/// fn example1(self: Arc) {} /// -/// trait MyTrait {} +/// // Trait has a function whose `self` type is `ArcBorrow<'_, Self>`. +/// fn example2(self: ArcBorrow<'_, Self>) {} +/// } /// /// struct Example; /// impl MyTrait for Example {} @@ -123,6 +129,9 @@ impl core::ops::Receiver for Arc {} // dynamically-sized type (DST) `U`. impl, U: ?Sized> core::ops::CoerceUnsized> for Arc {} +// This is to allow `Arc` to be dispatched on when `Arc` can be coerced into `Arc`. +impl, U: ?Sized> core::ops::DispatchFromDyn> for Arc {} + // SAFETY: It is safe to send `Arc` to another thread when the underlying `T` is `Sync` because // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs // `T` to be `Send` because any thread that has an `Arc` may ultimately access `T` directly, for @@ -297,6 +306,13 @@ pub struct ArcBorrow<'a, T: ?Sized + 'a> { // This is to allow [`ArcBorrow`] (and variants) to be used as the type of `self`. impl core::ops::Receiver for ArcBorrow<'_, T> {} +// This is to allow `ArcBorrow` to be dispatched on when `ArcBorrow` can be coerced into +// `ArcBorrow`. +impl, U: ?Sized> core::ops::DispatchFromDyn> + for ArcBorrow<'_, T> +{ +} + impl Clone for ArcBorrow<'_, T> { fn clone(&self) -> Self { *self