From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 374CBC55180 for ; Fri, 20 Feb 2026 09:53:07 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 98BD66B00A1; Fri, 20 Feb 2026 04:53:06 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 956C76B00A3; Fri, 20 Feb 2026 04:53:06 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8380A6B00A4; Fri, 20 Feb 2026 04:53:06 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 6A3366B00A1 for ; Fri, 20 Feb 2026 04:53:06 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 1D981140BF6 for ; Fri, 20 Feb 2026 09:53:06 +0000 (UTC) X-FDA: 84464371572.13.BA1D7C2 Received: from tor.source.kernel.org (tor.source.kernel.org [172.105.4.254]) by imf28.hostedemail.com (Postfix) with ESMTP id 5A51DC0006 for ; Fri, 20 Feb 2026 09:53:04 +0000 (UTC) Authentication-Results: imf28.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=IFtErZvi; spf=pass (imf28.hostedemail.com: domain of a.hindborg@kernel.org designates 172.105.4.254 as permitted sender) smtp.mailfrom=a.hindborg@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1771581184; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ucEq0VB0m0l95StFRjX3ZelUVV4NsNezze/QlcEO/l8=; b=wfiW9kcJtH8AWWe/V/rdU/JnIaCqh+8kZ872H+Wc/j9FCWAbZ6HY94uxGXvp0rdlzxGMGM dvWfDfhvJbfVRBY+JV3nnztKwCATEc1hms7FzBAqVfgm8UcTVZcGaUJl2JD/EmozdIsHJf 9mN6IInvErrku69OoveGX9+TLXplsjg= ARC-Authentication-Results: i=1; imf28.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=IFtErZvi; spf=pass (imf28.hostedemail.com: domain of a.hindborg@kernel.org designates 172.105.4.254 as permitted sender) smtp.mailfrom=a.hindborg@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1771581184; a=rsa-sha256; cv=none; b=Ys+wC4on/92csfVwIehfhtkvtH+yZFSo6o7JNqFqr+ZGnWTTAcj8dXlyX87VxEJQboejT7 lnNwmKcdRE+FHo+DzGtL1AAyQhlxsmUq92gC38Jah0A5gKMRmlIGWLplv7BZky7BXOyqNq xX3LPLqUJduy4NylT9esftSJJjAbBr4= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 76C0C60054; Fri, 20 Feb 2026 09:53:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71A23C116C6; Fri, 20 Feb 2026 09:52:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771581183; bh=ddK1ak//TXQr8RhJb4UqmdreS3kf7nw+QCC2K6EoCxw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IFtErZviVRIApr6JWYfKXzVbkUGI6C+9RufmKoBvnZqEeLCDWkVI3Q/SJtdTbCzQR vgoQlixEpBPL+9yLVAiikQxNm396Ai5Il9xiFoxQthJVJzcotcQ7nI5XiwFIh0CQye gP6zB2PvlxB663nMuu3+MsHDV5ipt+0TGbWvMbDAontvp8TfivE+XHVAxEPdTFuB22 h2ReNknc2LOBLPSLDqPQ15nHesOVmBZexzoR93HVXhx33ms6LPJ0ifL3Tq1AteTKn/ rgsINYFvJsGYdZ5pojR2KIQK8DQsWBkZ1PtTsnxWSVi3Q+j8fHa8WlwSOrZRugyvSj RFYh/fAGImvBg== From: Andreas Hindborg Date: Fri, 20 Feb 2026 10:51:11 +0100 Subject: [PATCH v15 2/9] rust: rename `AlwaysRefCounted` to `RefCounted`. MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260220-unique-ref-v15-2-893ed86b06cc@kernel.org> References: <20260220-unique-ref-v15-0-893ed86b06cc@kernel.org> In-Reply-To: <20260220-unique-ref-v15-0-893ed86b06cc@kernel.org> To: Miguel Ojeda , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Greg Kroah-Hartman , Dave Ertman , Ira Weiny , Leon Romanovsky , Paul Moore , Serge Hallyn , "Rafael J. Wysocki" , David Airlie , Simona Vetter , Alexander Viro , Christian Brauner , Jan Kara , Igor Korotin , Daniel Almeida , Lorenzo Stoakes , "Liam R. Howlett" , Viresh Kumar , Nishanth Menon , Stephen Boyd , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Boqun Feng , Boqun Feng Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-block@vger.kernel.org, linux-security-module@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-pm@vger.kernel.org, linux-pci@vger.kernel.org, Andreas Hindborg , Oliver Mangold , Viresh Kumar X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=34430; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=rrFhqQU4IAhH0CwwR7UUnxUjhCeP2K7g8e+HurhZR8Y=; b=owEBbQKS/ZANAwAKAeG4Gj55KGN3AcsmYgBpmC6fMCX27NHQuaTFZouXnIyuw2rXNVorCpirC nZ8sP1GM26JAjMEAAEKAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaZgunwAKCRDhuBo+eShj d8l2D/9MD4TS4CpKaoxKHuZEf/zrYfO+kjBz0KKeSa4OEoyT7aE7TbwtMwPAh+nfGD/weyi+Rka gQ2G5HZ/JE/6qTY14ApsC3tqiyW9prOkSBbY7iW0HemUWp8/biRmZRspIvhnCMG1M9vy52j8xTf dVcKg3lQBLah78mqZWx4tRjOWFN7yu59RNq+OjLl4BCWQPYF6V545CSxi9aSWjSjafshA32M3DH 66/nAGtmMiH9gRKSHbekNyHU4VCc4ca98QRYePObvT3gHRcM6IETZIM7mwV5TQO1vLh6+dv7vNj C1aXO3G7VyVP62+ConUn0aTzPCb+c/gbZCW6AMIcZMl3F22rg+1uas61nnW/ER7XrAWUH2U8BJx w99K8sGUFeAxMJ+5La5DR9J++AP+sLoz2qZEwMSTAUFrrNK068cEUutnqeZFZ1TiHc2MnrEJ5na R0+Tv8QHU3zroFYs8VT1kaltT5EnLTOPElU1bG6WU35+/SV0HetW6PCrVnt8eRnCmenu1lr30zw jawJQyuBySmIznRkhvM58Vd/iB6v0oZF6mII1y55IW+6lRYBmbiXLzzh6t1S/IXQX9BgHJFVyJc EkGI4EtC+NgIF5Af6fiHqEIOL91B75DhnLoENeuhG5W/bSu9XuO/qjj2BUbQwgVbqi+OujUPSXa oRsQSb1tT3x9u7w== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 X-Stat-Signature: ne83fkkkr71cb4e848fimyo3x7455iwe X-Rspam-User: X-Rspamd-Queue-Id: 5A51DC0006 X-Rspamd-Server: rspam01 X-HE-Tag: 1771581184-1631 X-HE-Meta: U2FsdGVkX19RUlG0voiVcB5al63qVKuBubW/CLA1Mo3bHMwyL5WCWva8+RlVcJx5HIicvHHPoRn8YSBTQQOeB1uwYABb07B1t0RExs2CLEQuGUNmfHCSRz70LTgj/ngsJ1poGfQGoPsWjm2Rphr94ICgiEI2VidLPnxTpXgTsCXHb8M+7z6tTqRxLn8vx+uRWjAdAIJE+nmEXGiRtDdBBLEAk9ksbLFvsf8M7S6PB0iIOT2x2YirguATEkF2jBpOucfUCTZTaLvJL9s+YENNLZSP10gCxjk2g79Hb1/2Z824pdNLZjH1v4TOBMOB/ci8xJ2Vj97FBIyhbtmYe13HB3V9PHgQce++ijJUCt7DjqaNZ7cN3pLsm51I5XklhTZngLtbyoX/lpbOT+RsWsaVYcPp2fel/MTpTI6L1iZvXM2/Sxsq4qVEJ1lhIBo9EOzmKLcqh26vSR7rS9kM/I0QFM21FS1T6zcPyWPN8eiR4Mks+OtdlXVMnogRyg6ZXxNe1hzXpNuAkBHW6D+7rAajHIplr1mIliD7Imeo9Npe76IA5MQFPCou6b5r8OUgFOQovKK7FgRyL6yAgbTKp/MyGWzaFcE0GKb0lMcg/3+wIlKy/VZux8/XunMTbNGUvhBm5snJqGd1LzqJGuYwe2vntGVatOzZYR6d6ARqXFS6GIK7wjfSgA02iM2McRg8mE7pmsuThmshUJmAhc5b19ePi4JOMeMxpWMVnLhHtjKmoFQLl+Da45VAwJFDUTNKu6q1KgGNvFTsP2WiRj6jx6z5+wiu5GuPqSldAWiT1k3FTg90mhexVyk9Uhf4aHljNc9mGwkR9qjAVREHk2gpw90HpFJ/cL5Wr5Fn7BU0XQpkGR3gw1bTUwRMoENogB3cQ2JUC4cEKaOsbcDyiMZsLHA77tsUwUFOB+ChipRWWgUped0cGNnuhzpbNnu3DCBJTeOdXiDlX9TpvQjE2dCex8V Km3fIgW7 yujyVscykWjKGu2Z8TadzHLKfcgjqBgZCp9F/6m0KNjk39BIqHwGCggTlNanoMciKMTkKhhvOT5y7mV7r1lvuatVdU8gvud34YGhoCGfXj1yVAu89uKIbJOSYJQskmzxEx0iEZXYFwIxbFAof7iC4n74N5zGut/3ZdQUuAYw7SL00sIp1UF2hUsXqt+Gd1h25LQUEngEBU3mGNt4lr2beT/mEromy5CDTQ7iGxEE+fSzGJQaXk3oazJPtip5+vQiXUdnHVFvtGbwjD+QpIaylQwzfw/MTT2uy4oYBQYTrmg7FmTsIZP2+EX7d7JkC6Cq8BaIjcFiUgn0b8nxMz6Y/solji+FCY99PmSvTXYacYivA8tvawGv78JOWgT4yLQ/r4tqEReupQp4SR86tA6/3hD6LWiFaYTPSduKDJkWV7qLs2soab2D5XVjYwhT32eeJoCznZPE9zQdjxbK5+vIXflV0WxARtvZvJYKUSxGFl96YAl59+Lbvlv6Szglm13lb6zOyuD8IxFTdPQBoIf2Xvbp9Fm7TcVFJEMIA/ox42HtHoUBuoEjjw3jGm4XwhWawRhmlfD024fPr4e78Shfkhjrn0g== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Oliver Mangold There are types where it may both be reference counted in some cases and owned in others. In such cases, obtaining `ARef` from `&T` would be unsound as it allows creation of `ARef` copy from `&Owned`. Therefore, we split `AlwaysRefCounted` into `RefCounted` (which `ARef` would require) and a marker trait to indicate that the type is always reference counted (and not `Ownable`) so the `&T` -> `ARef` conversion is possible. - Rename `AlwaysRefCounted` to `RefCounted`. - Add a new unsafe trait `AlwaysRefCounted`. - Implement the new trait `AlwaysRefCounted` for the newly renamed `RefCounted` implementations. This leaves functionality of existing implementers of `AlwaysRefCounted` intact. Suggested-by: Alice Ryhl Reviewed-by: Daniel Almeida Signed-off-by: Oliver Mangold [ Andreas: Updated commit message and rebase on rust-6.20-7.0 ] Acked-by: Igor Korotin Acked-by: Danilo Krummrich Acked-by: Viresh Kumar Reviewed-by: Gary Guo Co-developed-by: Andreas Hindborg Signed-off-by: Andreas Hindborg --- rust/kernel/auxiliary.rs | 7 +++++- rust/kernel/block/mq/request.rs | 15 +++++++------ rust/kernel/cred.rs | 13 ++++++++++-- rust/kernel/device.rs | 10 ++++++--- rust/kernel/device/property.rs | 7 +++++- rust/kernel/drm/device.rs | 10 ++++++--- rust/kernel/drm/gem/mod.rs | 8 ++++--- rust/kernel/fs/file.rs | 16 ++++++++++---- rust/kernel/i2c.rs | 16 +++++++++----- rust/kernel/mm.rs | 15 +++++++++---- rust/kernel/mm/mmput_async.rs | 9 ++++++-- rust/kernel/opp.rs | 10 ++++++--- rust/kernel/owned.rs | 2 +- rust/kernel/pci.rs | 10 ++++++++- rust/kernel/pid_namespace.rs | 12 +++++++++-- rust/kernel/platform.rs | 7 +++++- rust/kernel/sync/aref.rs | 47 ++++++++++++++++++++++++++--------------- rust/kernel/task.rs | 10 ++++++--- rust/kernel/types.rs | 3 ++- rust/kernel/usb.rs | 15 ++++++++++--- 20 files changed, 176 insertions(+), 66 deletions(-) diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index 56f3c180e8f69..234003341294f 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -11,6 +11,7 @@ driver, error::{from_result, to_result, Result}, prelude::*, + sync::aref::{AlwaysRefCounted, RefCounted}, types::Opaque, ThisModule, }; @@ -258,7 +259,7 @@ unsafe impl device::AsBusDevice for Device kernel::impl_device_context_into_aref!(Device); // SAFETY: Instances of `Device` are always reference-counted. -unsafe impl crate::sync::aref::AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::get_device(self.as_ref().as_raw()) }; @@ -277,6 +278,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + impl AsRef> for Device { fn as_ref(&self) -> &device::Device { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request.rs index ce3e30c81cb5e..cf013b9e2cacf 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -9,7 +9,7 @@ block::mq::Operations, error::Result, sync::{ - aref::{ARef, AlwaysRefCounted}, + aref::{ARef, AlwaysRefCounted, RefCounted}, atomic::Relaxed, Refcount, }, @@ -229,11 +229,10 @@ unsafe impl Send for Request {} // mutate `self` are internally synchronized` unsafe impl Sync for Request {} -// SAFETY: All instances of `Request` are reference counted. This -// implementation of `AlwaysRefCounted` ensure that increments to the ref count -// keeps the object alive in memory at least until a matching reference count -// decrement is executed. -unsafe impl AlwaysRefCounted for Request { +// SAFETY: All instances of `Request` are reference counted. This implementation of `RefCounted` +// ensure that increments to the ref count keeps the object alive in memory at least until a +// matching reference count decrement is executed. +unsafe impl RefCounted for Request { fn inc_ref(&self) { self.wrapper_ref().refcount().inc(); } @@ -255,3 +254,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull) { } } } + +// SAFETY: We currently do not implement `Ownable`, thus it is okay to obtain an `ARef` +// from a `&Request` (but this will change in the future). +unsafe impl AlwaysRefCounted for Request {} diff --git a/rust/kernel/cred.rs b/rust/kernel/cred.rs index ffa156b9df377..20ef0144094be 100644 --- a/rust/kernel/cred.rs +++ b/rust/kernel/cred.rs @@ -8,7 +8,12 @@ //! //! Reference: -use crate::{bindings, sync::aref::AlwaysRefCounted, task::Kuid, types::Opaque}; +use crate::{ + bindings, + sync::aref::RefCounted, + task::Kuid, + types::{AlwaysRefCounted, Opaque}, +}; /// Wraps the kernel's `struct cred`. /// @@ -76,7 +81,7 @@ pub fn euid(&self) -> Kuid { } // SAFETY: The type invariants guarantee that `Credential` is always ref-counted. -unsafe impl AlwaysRefCounted for Credential { +unsafe impl RefCounted for Credential { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -90,3 +95,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull) { unsafe { bindings::put_cred(obj.cast().as_ptr()) }; } } + +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Credential`. +unsafe impl AlwaysRefCounted for Credential {} diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 71b200df0f400..2a3bed19b9495 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -7,8 +7,8 @@ use crate::{ bindings, fmt, prelude::*, - sync::aref::ARef, - types::{ForeignOwnable, Opaque}, + sync::aref::{ARef, RefCounted}, + types::{AlwaysRefCounted, ForeignOwnable, Opaque}, }; use core::{any::TypeId, marker::PhantomData, ptr}; @@ -490,7 +490,7 @@ pub fn fwnode(&self) -> Option<&property::FwNode> { kernel::impl_device_context_into_aref!(Device); // SAFETY: Instances of `Device` are always reference-counted. -unsafe impl crate::sync::aref::AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::get_device(self.as_raw()) }; @@ -502,6 +502,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + // SAFETY: As by the type invariant `Device` can be sent to any thread. unsafe impl Send for Device {} diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs index 3a332a8c53a9e..a8bb824ad0ec1 100644 --- a/rust/kernel/device/property.rs +++ b/rust/kernel/device/property.rs @@ -14,6 +14,7 @@ fmt, prelude::*, str::{CStr, CString}, + sync::aref::{AlwaysRefCounted, RefCounted}, types::{ARef, Opaque}, }; @@ -359,7 +360,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } // SAFETY: Instances of `FwNode` are always reference-counted. -unsafe impl crate::types::AlwaysRefCounted for FwNode { +unsafe impl RefCounted for FwNode { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the // refcount is non-zero. @@ -373,6 +374,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&FwNode`. +unsafe impl AlwaysRefCounted for FwNode {} + enum Node<'a> { Borrowed(&'a FwNode), Owned(ARef), diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs index 3ce8f62a00569..38ce7f389ed00 100644 --- a/rust/kernel/drm/device.rs +++ b/rust/kernel/drm/device.rs @@ -11,8 +11,8 @@ error::from_err_ptr, error::Result, prelude::*, - sync::aref::{ARef, AlwaysRefCounted}, - types::Opaque, + sync::aref::{AlwaysRefCounted, RefCounted}, + types::{ARef, Opaque}, }; use core::{alloc::Layout, mem, ops::Deref, ptr, ptr::NonNull}; @@ -198,7 +198,7 @@ fn deref(&self) -> &Self::Target { // SAFETY: DRM device objects are always reference counted and the get/put functions // satisfy the requirements. -unsafe impl AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::drm_dev_get(self.as_raw()) }; @@ -213,6 +213,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + impl AsRef for Device { fn as_ref(&self) -> &device::Device { // SAFETY: `bindings::drm_device::dev` is valid as long as the DRM device itself is valid, diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index a7f682e95c018..ad6840a440165 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -10,8 +10,7 @@ drm::driver::{AllocImpl, AllocOps}, error::{to_result, Result}, prelude::*, - sync::aref::{ARef, AlwaysRefCounted}, - types::Opaque, + types::{ARef, AlwaysRefCounted, Opaque}, }; use core::{ops::Deref, ptr::NonNull}; @@ -253,7 +252,7 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { } // SAFETY: Instances of `Object` are always reference-counted. -unsafe impl crate::types::AlwaysRefCounted for Object { +unsafe impl crate::types::RefCounted for Object { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::drm_gem_object_get(self.as_raw()) }; @@ -267,6 +266,9 @@ unsafe fn dec_ref(obj: NonNull) { unsafe { bindings::drm_gem_object_put(obj.as_raw()) } } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Object`. +unsafe impl crate::types::AlwaysRefCounted for Object {} impl super::private::Sealed for Object {} diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs index 23ee689bd2400..06e457d62a939 100644 --- a/rust/kernel/fs/file.rs +++ b/rust/kernel/fs/file.rs @@ -12,8 +12,8 @@ cred::Credential, error::{code::*, to_result, Error, Result}, fmt, - sync::aref::{ARef, AlwaysRefCounted}, - types::{NotThreadSafe, Opaque}, + sync::aref::RefCounted, + types::{ARef, AlwaysRefCounted, NotThreadSafe, Opaque}, }; use core::ptr; @@ -197,7 +197,7 @@ unsafe impl Sync for File {} // SAFETY: The type invariants guarantee that `File` is always ref-counted. This implementation // makes `ARef` own a normal refcount. -unsafe impl AlwaysRefCounted for File { +unsafe impl RefCounted for File { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -212,6 +212,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&File`. +unsafe impl AlwaysRefCounted for File {} + /// Wraps the kernel's `struct file`. Not thread safe. /// /// This type represents a file that is not known to be safe to transfer across thread boundaries. @@ -233,7 +237,7 @@ pub struct LocalFile { // SAFETY: The type invariants guarantee that `LocalFile` is always ref-counted. This implementation // makes `ARef` own a normal refcount. -unsafe impl AlwaysRefCounted for LocalFile { +unsafe impl RefCounted for LocalFile { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -249,6 +253,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&LocalFile`. +unsafe impl AlwaysRefCounted for LocalFile {} + impl LocalFile { /// Constructs a new `struct file` wrapper from a file descriptor. /// diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs index 792a71b154630..683950057423d 100644 --- a/rust/kernel/i2c.rs +++ b/rust/kernel/i2c.rs @@ -17,8 +17,10 @@ of, prelude::*, types::{ + ARef, AlwaysRefCounted, - Opaque, // + Opaque, + RefCounted, // }, // }; @@ -31,8 +33,6 @@ }, // }; -use kernel::types::ARef; - /// An I2C device id table. #[repr(transparent)] #[derive(Clone, Copy)] @@ -407,7 +407,7 @@ pub fn get(index: i32) -> Result> { kernel::impl_device_context_into_aref!(I2cAdapter); // SAFETY: Instances of `I2cAdapter` are always reference-counted. -unsafe impl crate::types::AlwaysRefCounted for I2cAdapter { +unsafe impl crate::types::RefCounted for I2cAdapter { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::i2c_get_adapter(self.index()) }; @@ -418,6 +418,9 @@ unsafe fn dec_ref(obj: NonNull) { unsafe { bindings::i2c_put_adapter(obj.as_ref().as_raw()) } } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from an +// `&I2cAdapter`. +unsafe impl AlwaysRefCounted for I2cAdapter {} /// The i2c board info representation /// @@ -483,7 +486,7 @@ unsafe impl device::AsBusDevice for I2cClient) { unsafe { bindings::put_device(&raw mut (*obj.as_ref().as_raw()).dev) } } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from an +// `&I2cClient`. +unsafe impl AlwaysRefCounted for I2cClient {} impl AsRef> for I2cClient { fn as_ref(&self) -> &device::Device { diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index 4764d7b68f2a7..dd9e3969e7206 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -13,8 +13,8 @@ use crate::{ bindings, - sync::aref::{ARef, AlwaysRefCounted}, - types::{NotThreadSafe, Opaque}, + sync::aref::RefCounted, + types::{ARef, AlwaysRefCounted, NotThreadSafe, Opaque}, }; use core::{ops::Deref, ptr::NonNull}; @@ -55,7 +55,7 @@ unsafe impl Send for Mm {} unsafe impl Sync for Mm {} // SAFETY: By the type invariants, this type is always refcounted. -unsafe impl AlwaysRefCounted for Mm { +unsafe impl RefCounted for Mm { #[inline] fn inc_ref(&self) { // SAFETY: The pointer is valid since self is a reference. @@ -69,6 +69,9 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a `&Mm`. +unsafe impl AlwaysRefCounted for Mm {} + /// A wrapper for the kernel's `struct mm_struct`. /// /// This type is like [`Mm`], but with non-zero `mm_users`. It can only be used when `mm_users` can @@ -91,7 +94,7 @@ unsafe impl Send for MmWithUser {} unsafe impl Sync for MmWithUser {} // SAFETY: By the type invariants, this type is always refcounted. -unsafe impl AlwaysRefCounted for MmWithUser { +unsafe impl RefCounted for MmWithUser { #[inline] fn inc_ref(&self) { // SAFETY: The pointer is valid since self is a reference. @@ -105,6 +108,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&MmWithUser`. +unsafe impl AlwaysRefCounted for MmWithUser {} + // Make all `Mm` methods available on `MmWithUser`. impl Deref for MmWithUser { type Target = Mm; diff --git a/rust/kernel/mm/mmput_async.rs b/rust/kernel/mm/mmput_async.rs index b8d2f051225c7..aba4ce675c860 100644 --- a/rust/kernel/mm/mmput_async.rs +++ b/rust/kernel/mm/mmput_async.rs @@ -10,7 +10,8 @@ use crate::{ bindings, mm::MmWithUser, - sync::aref::{ARef, AlwaysRefCounted}, + sync::aref::RefCounted, + types::{ARef, AlwaysRefCounted}, }; use core::{ops::Deref, ptr::NonNull}; @@ -34,7 +35,7 @@ unsafe impl Send for MmWithUserAsync {} unsafe impl Sync for MmWithUserAsync {} // SAFETY: By the type invariants, this type is always refcounted. -unsafe impl AlwaysRefCounted for MmWithUserAsync { +unsafe impl RefCounted for MmWithUserAsync { #[inline] fn inc_ref(&self) { // SAFETY: The pointer is valid since self is a reference. @@ -48,6 +49,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` +// from a `&MmWithUserAsync`. +unsafe impl AlwaysRefCounted for MmWithUserAsync {} + // Make all `MmWithUser` methods available on `MmWithUserAsync`. impl Deref for MmWithUserAsync { type Target = MmWithUser; diff --git a/rust/kernel/opp.rs b/rust/kernel/opp.rs index a760fac287655..06fe2ca776a4f 100644 --- a/rust/kernel/opp.rs +++ b/rust/kernel/opp.rs @@ -16,8 +16,8 @@ ffi::{c_char, c_ulong}, prelude::*, str::CString, - sync::aref::{ARef, AlwaysRefCounted}, - types::Opaque, + sync::aref::RefCounted, + types::{ARef, AlwaysRefCounted, Opaque}, }; #[cfg(CONFIG_CPU_FREQ)] @@ -1041,7 +1041,7 @@ unsafe impl Send for OPP {} unsafe impl Sync for OPP {} /// SAFETY: The type invariants guarantee that [`OPP`] is always refcounted. -unsafe impl AlwaysRefCounted for OPP { +unsafe impl RefCounted for OPP { fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. unsafe { bindings::dev_pm_opp_get(self.0.get()) }; @@ -1053,6 +1053,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from an +// `&OPP`. +unsafe impl AlwaysRefCounted for OPP {} + impl OPP { /// Creates an owned reference to a [`OPP`] from a valid pointer. /// diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs index d566ad0aa1c99..b8d3b9c725cf6 100644 --- a/rust/kernel/owned.rs +++ b/rust/kernel/owned.rs @@ -25,7 +25,7 @@ /// /// Note: The underlying object is not required to provide internal reference counting, because it /// represents a unique, owned reference. If reference counting (on the Rust side) is required, -/// [`AlwaysRefCounted`](crate::types::AlwaysRefCounted) should be implemented. +/// [`RefCounted`](crate::types::RefCounted) should be implemented. /// /// # Safety /// diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 82e128431f080..a73551dedee8f 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -19,6 +19,10 @@ }, prelude::*, str::CStr, + sync::aref::{ + AlwaysRefCounted, + RefCounted, // + }, types::Opaque, ThisModule, // }; @@ -458,7 +462,7 @@ unsafe impl device::AsBusDevice for Device impl crate::dma::Device for Device {} // SAFETY: Instances of `Device` are always reference-counted. -unsafe impl crate::sync::aref::AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::pci_dev_get(self.as_raw()) }; @@ -470,6 +474,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + impl AsRef> for Device { fn as_ref(&self) -> &device::Device { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid diff --git a/rust/kernel/pid_namespace.rs b/rust/kernel/pid_namespace.rs index 979a9718f153d..4f6a94540e33d 100644 --- a/rust/kernel/pid_namespace.rs +++ b/rust/kernel/pid_namespace.rs @@ -7,7 +7,11 @@ //! C header: [`include/linux/pid_namespace.h`](srctree/include/linux/pid_namespace.h) and //! [`include/linux/pid.h`](srctree/include/linux/pid.h) -use crate::{bindings, sync::aref::AlwaysRefCounted, types::Opaque}; +use crate::{ + bindings, + sync::aref::RefCounted, + types::{AlwaysRefCounted, Opaque}, +}; use core::ptr; /// Wraps the kernel's `struct pid_namespace`. Thread safe. @@ -41,7 +45,7 @@ pub unsafe fn from_ptr<'a>(ptr: *const bindings::pid_namespace) -> &'a Self { } // SAFETY: Instances of `PidNamespace` are always reference-counted. -unsafe impl AlwaysRefCounted for PidNamespace { +unsafe impl RefCounted for PidNamespace { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -55,6 +59,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from +// a `&PidNamespace`. +unsafe impl AlwaysRefCounted for PidNamespace {} + // SAFETY: // - `PidNamespace::dec_ref` can be called from any thread. // - It is okay to send ownership of `PidNamespace` across thread boundaries. diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index ed889f079cab6..9f1cd0b8fb0bc 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -13,6 +13,7 @@ irq::{self, IrqRequest}, of, prelude::*, + sync::aref::{AlwaysRefCounted, RefCounted}, types::Opaque, ThisModule, }; @@ -481,7 +482,7 @@ pub fn optional_irq_by_name(&self, name: &CStr) -> Result> { impl crate::dma::Device for Device {} // SAFETY: Instances of `Device` are always reference-counted. -unsafe impl crate::sync::aref::AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::get_device(self.as_ref().as_raw()) }; @@ -493,6 +494,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + impl AsRef> for Device { fn as_ref(&self) -> &device::Device { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs index e175aefe86151..61caddfd89619 100644 --- a/rust/kernel/sync/aref.rs +++ b/rust/kernel/sync/aref.rs @@ -19,11 +19,9 @@ use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull}; -/// Types that are _always_ reference counted. +/// Types that are internally reference counted. /// /// It allows such types to define their own custom ref increment and decrement functions. -/// Additionally, it allows users to convert from a shared reference `&T` to an owned reference -/// [`ARef`]. /// /// This is usually implemented by wrappers to existing structures on the C side of the code. For /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted @@ -40,9 +38,8 @@ /// at least until matching decrements are performed. /// /// Implementers must also ensure that all instances are reference-counted. (Otherwise they -/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object -/// alive.) -pub unsafe trait AlwaysRefCounted { +/// won't be able to honour the requirement that [`RefCounted::inc_ref`] keep the object alive.) +pub unsafe trait RefCounted { /// Increments the reference count on the object. fn inc_ref(&self); @@ -55,11 +52,27 @@ pub unsafe trait AlwaysRefCounted { /// Callers must ensure that there was a previous matching increment to the reference count, /// and that the object is no longer used after its reference count is decremented (as it may /// result in the object being freed), unless the caller owns another increment on the refcount - /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls - /// [`AlwaysRefCounted::dec_ref`] once). + /// (e.g., it calls [`RefCounted::inc_ref`] twice, then calls [`RefCounted::dec_ref`] once). unsafe fn dec_ref(obj: NonNull); } +/// Always reference-counted type. +/// +/// It allows deriving a counted reference [`ARef`] from a `&T`. +/// +/// This provides some convenience, but it allows "escaping" borrow checks on `&T`. As it +/// complicates attempts to ensure that a reference to T is unique, it is optional to provide for +/// [`RefCounted`] types. See *Safety* below. +/// +/// # Safety +/// +/// Implementers must ensure that no safety invariants are violated by upgrading an `&T` to an +/// [`ARef`]. In particular that implies [`AlwaysRefCounted`] and [`crate::types::Ownable`] +/// cannot be implemented for the same type, as this would allow violating the uniqueness guarantee +/// of [`crate::types::Owned`] by dereferencing it into an `&T` and obtaining an [`ARef`] from +/// that. +pub unsafe trait AlwaysRefCounted: RefCounted {} + /// An owned reference to an always-reference-counted object. /// /// The object's reference count is automatically decremented when an instance of [`ARef`] is @@ -70,7 +83,7 @@ pub unsafe trait AlwaysRefCounted { /// /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count. -pub struct ARef { +pub struct ARef { ptr: NonNull, _p: PhantomData, } @@ -79,16 +92,16 @@ pub struct ARef { // 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 `ARef` may ultimately access `T` using a // mutable reference, for example, when the reference count reaches zero and `T` is dropped. -unsafe impl Send for ARef {} +unsafe impl Send for ARef {} // SAFETY: It is safe to send `&ARef` 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 a `&ARef` may clone it and get an // `ARef` on that thread, so the thread may ultimately access `T` using a mutable reference, for // example, when the reference count reaches zero and `T` is dropped. -unsafe impl Sync for ARef {} +unsafe impl Sync for ARef {} -impl ARef { +impl ARef { /// Creates a new instance of [`ARef`]. /// /// It takes over an increment of the reference count on the underlying object. @@ -117,12 +130,12 @@ pub unsafe fn from_raw(ptr: NonNull) -> Self { /// /// ``` /// use core::ptr::NonNull; - /// use kernel::sync::aref::{ARef, AlwaysRefCounted}; + /// use kernel::sync::aref::{ARef, RefCounted}; /// /// struct Empty {} /// /// # // SAFETY: TODO. - /// unsafe impl AlwaysRefCounted for Empty { + /// unsafe impl RefCounted for Empty { /// fn inc_ref(&self) {} /// unsafe fn dec_ref(_obj: NonNull) {} /// } @@ -140,7 +153,7 @@ pub fn into_raw(me: Self) -> NonNull { } } -impl Clone for ARef { +impl Clone for ARef { fn clone(&self) -> Self { self.inc_ref(); // SAFETY: We just incremented the refcount above. @@ -148,7 +161,7 @@ fn clone(&self) -> Self { } } -impl Deref for ARef { +impl Deref for ARef { type Target = T; fn deref(&self) -> &Self::Target { @@ -165,7 +178,7 @@ fn from(b: &T) -> Self { } } -impl Drop for ARef { +impl Drop for ARef { fn drop(&mut self) { // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to // decrement. diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index 49fad6de06740..0a6e38d984560 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -9,8 +9,8 @@ ffi::{c_int, c_long, c_uint}, mm::MmWithUser, pid_namespace::PidNamespace, - sync::aref::ARef, - types::{NotThreadSafe, Opaque}, + sync::aref::{AlwaysRefCounted, RefCounted}, + types::{ARef, NotThreadSafe, Opaque}, }; use core::{ cmp::{Eq, PartialEq}, @@ -348,7 +348,7 @@ pub fn active_pid_ns(&self) -> Option<&PidNamespace> { } // SAFETY: The type invariants guarantee that `Task` is always refcounted. -unsafe impl crate::sync::aref::AlwaysRefCounted for Task { +unsafe impl RefCounted for Task { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -362,6 +362,10 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Task`. +unsafe impl AlwaysRefCounted for Task {} + impl Kuid { /// Get the current euid. #[inline] diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 4aec7b699269a..9b96aa2ebdb7e 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -18,7 +18,8 @@ }, sync::aref::{ ARef, - AlwaysRefCounted, // + AlwaysRefCounted, + RefCounted, // }, // }; diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index d10b65e9fb6ad..089823b608333 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -12,7 +12,8 @@ error::{from_result, to_result, Result}, prelude::*, str::CStr, - types::{AlwaysRefCounted, Opaque}, + sync::aref::{AlwaysRefCounted, RefCounted}, + types::Opaque, ThisModule, }; use core::{ @@ -365,7 +366,7 @@ fn as_ref(&self) -> &Device { } // SAFETY: Instances of `Interface` are always reference-counted. -unsafe impl AlwaysRefCounted for Interface { +unsafe impl RefCounted for Interface { fn inc_ref(&self) { // SAFETY: The invariants of `Interface` guarantee that `self.as_raw()` // returns a valid `struct usb_interface` pointer, for which we will @@ -379,6 +380,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Interface`. +unsafe impl AlwaysRefCounted for Interface {} + // SAFETY: A `Interface` is always reference-counted and can be released from any thread. unsafe impl Send for Interface {} @@ -416,7 +421,7 @@ fn as_raw(&self) -> *mut bindings::usb_device { kernel::impl_device_context_into_aref!(Device); // SAFETY: Instances of `Device` are always reference-counted. -unsafe impl AlwaysRefCounted for Device { +unsafe impl RefCounted for Device { fn inc_ref(&self) { // SAFETY: The invariants of `Device` guarantee that `self.as_raw()` // returns a valid `struct usb_device` pointer, for which we will @@ -430,6 +435,10 @@ unsafe fn dec_ref(obj: NonNull) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef` from a +// `&Device`. +unsafe impl AlwaysRefCounted for Device {} + impl AsRef> for Device { fn as_ref(&self) -> &device::Device { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid -- 2.51.2