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 8517ECD4F26 for ; Fri, 26 Jun 2026 11:55:45 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 755B96B0130; Fri, 26 Jun 2026 07:55:44 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 706476B0132; Fri, 26 Jun 2026 07:55:44 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5A79E6B0133; Fri, 26 Jun 2026 07:55:44 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 20C086B0130 for ; Fri, 26 Jun 2026 07:55:44 -0400 (EDT) Received: from smtpin17.hostedemail.com (lb01a-stub [10.200.18.249]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 9F3E4A0427 for ; Fri, 26 Jun 2026 11:55:43 +0000 (UTC) X-FDA: 84921909366.17.83F93B4 Received: from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31]) by imf03.hostedemail.com (Postfix) with ESMTP id B150220004 for ; Fri, 26 Jun 2026 11:55:41 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20260515 header.b=E1IRl0ei; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf03.hostedemail.com: domain of a.hindborg@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=a.hindborg@kernel.org ARC-Seal: i=1; a=rsa-sha256; d=hostedemail.com; s=arc-20220608; cv=none; t=1782474941; b=xW49MJvbEGyiJtSufH1bBWiHwO7ETFXjsSWeLjeQwMOBLXzPVu8nzF3mHejvB9JojDl9/e +N8qlereIYyzaWOWMsZXR5S5Jct4grN//7izenYi9NxIbt6D38eWuCkjqPb9Zn/GqYVK+E cr+fnjyFdMlu1o/TvUCvXV0hl78DEzs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1782474941; 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=IGEKVKFVZNVk1+RmVgzF30xF6YgxgNVpGsqZC2WxOns=; b=VOzBBVULIBaekBGakBxp8lA/TjKRaRc90TWw/zwu24w/DzDL55x+pRTiQ0wayyrEQAb4ZI 7O9rxGBm377TzumDVeBnnEooGtW4rz+SU3ECICH5fW7P9/5LF7735zl8MM5bmOWFcINGPW K+XxgrPrthddBi3wfj925ysC+VmAK9I= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20260515 header.b=E1IRl0ei; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf03.hostedemail.com: domain of a.hindborg@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=a.hindborg@kernel.org Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id A4B4C4027F; Fri, 26 Jun 2026 11:55:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 35F5A1F00A3D; Fri, 26 Jun 2026 11:55:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1782474940; bh=IGEKVKFVZNVk1+RmVgzF30xF6YgxgNVpGsqZC2WxOns=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=E1IRl0eivr6Z99U8il9idrdCDm0NsLRp0CosMU3L7fk3LgRwZ3JzVuVqidxBu4yV4 OAaEqkhCrqEvmCnXjArRo+ctF4v3gKk+JfTbAaolbyRv+QAXFOkFS6VPjPs6Ujq8jH lGhrYnaXk7W0l4pBmRczdzNHToh1xy+7obn/6flX2mRTnWlt79ISg09nXsh+whlYKS V6sEVpS0OzIt5Tc5Jx0f7/j4AGYEGmrX5JW5sRqX+vTc7FBLe+1ULn/Drlu+UU/ED3 9jKCzFQ25Lot97b9MtcQcy48Told+kZJndiTAvVL282Pe8RI/HbbZClpgsVaQH548D m6qgGce03uGWA== From: Andreas Hindborg Date: Fri, 26 Jun 2026 13:54:02 +0200 Subject: [PATCH v19 5/8] rust: rename `AlwaysRefCounted` to `RefCounted`. MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260626-unique-ref-v19-5-2607ca88dfdf@kernel.org> References: <20260626-unique-ref-v19-0-2607ca88dfdf@kernel.org> In-Reply-To: <20260626-unique-ref-v19-0-2607ca88dfdf@kernel.org> To: Danilo Krummrich , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lyude Paul , Greg Kroah-Hartman , =?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Christian Brauner , Carlos Llamas , "Rafael J. Wysocki" , Dave Ertman , Ira Weiny , Leon Romanovsky , Paul Moore , Serge Hallyn , David Airlie , Simona Vetter , Alexander Viro , Jan Kara , Igor Korotin , Viresh Kumar , Nishanth Menon , Stephen Boyd , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Pavel Tikhomirov , Michal Wilczynski Cc: Andreas Hindborg , Philipp Stanner , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, driver-core@lists.linux.dev, linux-block@vger.kernel.org, linux-security-module@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-fsdevel@vger.kernel.org, linux-pm@vger.kernel.org, linux-pci@vger.kernel.org, linux-pwm@vger.kernel.org, Oliver Mangold , Viresh Kumar , Igor Korotin X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=39475; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=KeTm4SeXrKKGxF05HEt1R59iI3+B+CLRZiH9cKzash4=; b=owEBbQKS/ZANAwAKAfpQKQiqxb3QAcsmYgBqPmh4tlg1JZ/NaxmbKr0YhqCLET1RMWX/rbcef w2uN1rItfGJAjMEAAEKAB0WIQRXitnI2WZ2JirAaob6UCkIqsW90AUCaj5oeAAKCRD6UCkIqsW9 0DyID/4oIMtbgYqNNdFVciS+MCcEOfwjv5zLemv8+ZKEzqhihybWEeO7gaX6n0krWj4GYYqjuK8 mOZQ7TFG3ToQ87Sp78uar4YZLdpJUlYQxBlHulSk4g6P5+dUOlMPA0tiBuiNCKwCL20E+jpiPtF PO3fs5vwquAyy3dsCzRlVyiNWSrfphnnkFNFrkVLcCYzx9mDraXEPEll2pPaKynUFGdrvBKennm 5mbCi2KBd9zNWwPFhizCBhcEtTHU7PYYwHOUMwyvJvh64cQpImch/+7IbPWHwqZzr0Mmc8XvnPF qpn6pppo2IvK3A1Y7DAeJMsP0CJR73YDZqUsbR7oSv9AclNlfgMhFTEdmG60QM6Nnk5GErG7Zrc guRNgn+3d6axximlOfTlD8Gylh99ewBVAg6iAWvnInxztQTUfQhC+pmCP/Qtih0Offdomrc//YI LAPS+z4lt3yzdDI8XBv7LsYmSypBcMQ7HVW04UQqusMW8k26dcGIj8/70Y23jXb7YLbs0klT53p /qUPV4YgOCc3QZQ8dzMmDZ8uzLbTYGV0Gf9ZA+9pO5xlvZpotgOe3F23KyIcG86F/ugrKgRxcSB qBzO11MiiKekmVJ3Tc1N/ujT7QWW3DI6vyWhTIujuxlCgIzsgc7Dpn0en4upvR5/8E3f7TknjzC ZelVd1yUESptyHA== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: B150220004 X-Rspam-User: X-Stat-Signature: n8idhrpd7d1ama81gichh4sesn33swuq X-HE-Tag: 1782474941-696107 X-HE-Meta: U2FsdGVkX18KyfPOWVOxYRtRx1LitoaFS4LZWr2apwJ2P/VBVsP5j6RQf1xQSf3VOl194HVmjtNmiMjFv2fqwOwwtB90OgtcksqtRECxL8M1RXpQxtNmnQWrNgjDl94Y4wt1oY96ms2s6RP8fmTLwYw3iudwIQBg8EbSXF0pMhcNY1T9/Tdytez2ukt+CNJY1OTfYWs/e5dvf+tqILyctyCdUVmrBdk0A24FY1YOujK47dmUFS+cQoAEK1nFvJsZcBL6kvC/Ou8DhRaRjbP9p3IkkgHTJ/9BRoqWr6LtTWtK4u5pR4U9M1ePos8vHA/aJdCNNZn281J8ETbOR3Mgp8+ChTFMX1aZsyijSQSF1pKe5JyvpmbXjq9KqQ5Y6Y1ZT30Q4Xaie7BjU22tv8iXKv5ytUX53HnVX6EuY9XzM95rvoksiIzMuG+3Zs73+B4hmw0yFbu7UedMqJsB8R0TFrg3DE2UpkfJCK6hObfXDCNebTwlgcmlxatutyVmRIdKHN/Vg8zU+p6q3IKWIl+gLyiErW615IZGQr7ot2RMRJls3L1JYZDWK5uFq+4eovhrPDAw7xEP47izINqd0jaRBUFENWSMmQ/jxywUgKdc0t9OIb0MNs8aHg8+eq+5Pe3A1I4ugdM221/2U0mOZbxejpglYSO7BvofiVbtlh0YqKFBOCg+Q2jRrDG47fsviDfLhr1Lz8gMOcvBVIo9LnTs2tJQElxTtl63K1Q10k7mDdsbeaaYQObUnZ+7MM5oIgqD1SQEmlnV98WCyQ6FlqUEzR2O2bIzbl+x3BiXwDgGfivVTtw1fc5WOHtjOSx1Tq+ziedi3zRDEqEXReHiH1ucgMmmNVPCh76giqg45AyFiVTnPP2XiZQueklI1gSwuUeYlHV+6vtc7YlK4wjBV8TK0ghmcgFc7M9x5pcsfaEmOP0hwjd9UGAvwkYr9yDcGf29NsIFyy9DAi6med3XAEA FeneEAqS bgNEq/G6dNZBJPB3mvzj+hd7LIxL+7bACPzElGYvYd9X45hU27RMgi/AEW2lES4VDC3nOYU6WYfi0Q1F5uyKypjAhagQu2JxoRrYG4Pn5qnPuppuLoAMRplrxkBlEoafhPWj3j/Cafnfmd/HGqheMpzu+wky/VoKdoTm3adwD3uldNQrsbFx8B9RczAuAgtGk7VJg1R/oPnn1KVQtt9SQGh0/Sm5dCDg+68a/JI294N/rA7brU0RB9L9XGKVNLmqJOKJVCA6f1WhMf+b+VTh4tQUWk3JGKwTG5L9U4gicqkRQ0IJIRH314jMBWYFnwREYAB33uX2HgNVcYszNwQF0PPRS+BnI/boQrI5kQ6lz41pSHiIxDQNpAjeEIIZw4qDKPMOHBu7aJJqBY29JSjSBH8QA3fD+wSMQl88y5FHhc4btZB4B2lWXITrA6qX7kfnojxOmPFV3LaEk8KS5/UAzE1x6ndtrypU4MS9t/FSblhbMzgTvlJaQMeiM9pLRuBeEIhazoMNVyqj5CaHnVNVfp+TbXWW6U03gwMpibeJoraW3h1P1TXH2w+NJ8A== 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-next (7.2) ] 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 | 10 ++++++- rust/kernel/block/mq/request.rs | 19 ++++++++----- rust/kernel/cred.rs | 16 +++++++++-- rust/kernel/device.rs | 12 +++++++-- rust/kernel/device/property.rs | 11 ++++++-- rust/kernel/drm/device.rs | 9 +++++-- rust/kernel/drm/gem/mod.rs | 16 ++++++++--- rust/kernel/fs/file.rs | 23 +++++++++++++--- rust/kernel/i2c.rs | 13 ++++++--- rust/kernel/mm.rs | 22 ++++++++++++--- rust/kernel/mm/mmput_async.rs | 12 +++++++-- rust/kernel/opp.rs | 16 ++++++++--- rust/kernel/owned.rs | 2 +- rust/kernel/pci.rs | 10 ++++++- rust/kernel/pid_namespace.rs | 15 +++++++++-- rust/kernel/platform.rs | 10 ++++++- rust/kernel/pwm.rs | 12 +++++++-- rust/kernel/sync/aref.rs | 59 +++++++++++++++++++++++++---------------- rust/kernel/task.rs | 13 +++++++-- rust/kernel/types.rs | 12 ++++++--- rust/kernel/usb.rs | 17 +++++++++--- rust/kernel/workqueue.rs | 8 +++--- 22 files changed, 260 insertions(+), 77 deletions(-) diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index c42928d5a2393..854525289c8b4 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -19,6 +19,10 @@ to_result, // }, prelude::*, + sync::aref::{ + AlwaysRefCounted, + RefCounted, // + }, types::{ ForLt, ForeignOwnable, @@ -344,7 +348,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()) }; @@ -363,6 +367,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..8dad15ae4cfb0 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -9,7 +9,11 @@ block::mq::Operations, error::Result, sync::{ - aref::{ARef, AlwaysRefCounted}, + aref::{ + ARef, + AlwaysRefCounted, + RefCounted, // + }, atomic::Relaxed, Refcount, }, @@ -229,11 +233,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 +258,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..b17736a9adcd5 100644 --- a/rust/kernel/cred.rs +++ b/rust/kernel/cred.rs @@ -8,7 +8,15 @@ //! //! 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 +84,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 +98,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 645afc49a27d6..2e90f6a06fd05 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -8,8 +8,12 @@ bindings, fmt, prelude::*, - sync::aref::ARef, + sync::aref::{ + ARef, + RefCounted, // + }, types::{ + AlwaysRefCounted, ForeignOwnable, Opaque, // }, // @@ -448,7 +452,7 @@ pub fn name(&self) -> &CStr { 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()) }; @@ -460,6 +464,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 5aead835fbbc0..cee7e25013689 100644 --- a/rust/kernel/device/property.rs +++ b/rust/kernel/device/property.rs @@ -14,7 +14,10 @@ fmt, prelude::*, str::{CStr, CString}, - sync::aref::ARef, + sync::aref::{ + ARef, + AlwaysRefCounted, // + }, types::Opaque, }; @@ -360,7 +363,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } // SAFETY: Instances of `FwNode` are always reference-counted. -unsafe impl crate::sync::aref::AlwaysRefCounted for FwNode { +unsafe impl crate::sync::aref::RefCounted for FwNode { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the // refcount is non-zero. @@ -374,6 +377,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 403fc35353c74..368742a258376 100644 --- a/rust/kernel/drm/device.rs +++ b/rust/kernel/drm/device.rs @@ -15,7 +15,8 @@ prelude::*, sync::aref::{ ARef, - AlwaysRefCounted, // + AlwaysRefCounted, + RefCounted, // }, types::Opaque, workqueue::{ @@ -227,7 +228,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()) }; @@ -242,6 +243,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 01b5bd47a3332..30d3718578fe8 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -17,7 +17,7 @@ prelude::*, sync::aref::{ ARef, - AlwaysRefCounted, // + RefCounted, // }, types::Opaque, }; @@ -29,7 +29,7 @@ #[cfg(CONFIG_RUST_DRM_GEM_SHMEM_HELPER)] pub mod shmem; -/// A macro for implementing [`AlwaysRefCounted`] for any GEM object type. +/// A macro for implementing [`RefCounted`] for any GEM object type. /// /// Since all GEM objects use the same refcounting scheme. #[macro_export] @@ -42,7 +42,7 @@ impl $( <$( $tparam_id:ident ),+> )? for $type:ty )? ) => { // SAFETY: All GEM objects are refcounted. - unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::AlwaysRefCounted for $type + unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::RefCounted for $type where Self: IntoGEMObject, $( $( $bind_param : $bind_trait ),+ )? @@ -61,6 +61,14 @@ unsafe fn dec_ref(obj: core::ptr::NonNull) { unsafe { bindings::drm_gem_object_put(obj) }; } } + + // SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<$type>` from a + // `&$type`. + unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::AlwaysRefCounted for $type + where + Self: IntoGEMObject, + $( $( $bind_param : $bind_trait ),+ )? + {} }; } #[cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), allow(unused))] @@ -98,7 +106,7 @@ fn close(_obj: &::Object, _file: &DriverFile) } /// Trait that represents a GEM object subtype -pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted { +pub trait IntoGEMObject: Sized + super::private::Sealed + RefCounted { /// Returns a reference to the raw `drm_gem_object` structure, which must be valid as long as /// this owning object is valid. fn as_raw(&self) -> *mut bindings::drm_gem_object; diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs index 23ee689bd2400..720e57418358d 100644 --- a/rust/kernel/fs/file.rs +++ b/rust/kernel/fs/file.rs @@ -12,8 +12,15 @@ cred::Credential, error::{code::*, to_result, Error, Result}, fmt, - sync::aref::{ARef, AlwaysRefCounted}, - types::{NotThreadSafe, Opaque}, + sync::aref::{ + ARef, + RefCounted, // + }, + types::{ + AlwaysRefCounted, + NotThreadSafe, + Opaque, // + }, // }; use core::ptr; @@ -197,7 +204,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 +219,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 +244,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 +260,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 624b971ca8b0b..02b2c9220eb11 100644 --- a/rust/kernel/i2c.rs +++ b/rust/kernel/i2c.rs @@ -18,7 +18,8 @@ prelude::*, sync::aref::{ ARef, - AlwaysRefCounted, // + AlwaysRefCounted, + RefCounted, // }, types::Opaque, // }; @@ -424,7 +425,7 @@ pub fn get(index: i32) -> Result> { kernel::impl_device_context_into_aref!(I2cAdapter); // SAFETY: Instances of `I2cAdapter` are always reference-counted. -unsafe impl AlwaysRefCounted for I2cAdapter { +unsafe impl 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()) }; @@ -435,6 +436,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 /// @@ -500,7 +504,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..83ed94fca14ca 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -13,8 +13,15 @@ use crate::{ bindings, - sync::aref::{ARef, AlwaysRefCounted}, - types::{NotThreadSafe, Opaque}, + sync::aref::{ + ARef, + RefCounted, // + }, + types::{ + AlwaysRefCounted, + NotThreadSafe, + Opaque, // + }, // }; use core::{ops::Deref, ptr::NonNull}; @@ -55,7 +62,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 +76,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 +101,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 +115,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..8fbc396e46028 100644 --- a/rust/kernel/mm/mmput_async.rs +++ b/rust/kernel/mm/mmput_async.rs @@ -10,7 +10,11 @@ use crate::{ bindings, mm::MmWithUser, - sync::aref::{ARef, AlwaysRefCounted}, + sync::aref::{ + ARef, + RefCounted, // + }, + types::AlwaysRefCounted, }; use core::{ops::Deref, ptr::NonNull}; @@ -34,7 +38,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 +52,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 62e44676125d1..b8db6bdefd077 100644 --- a/rust/kernel/opp.rs +++ b/rust/kernel/opp.rs @@ -16,8 +16,14 @@ ffi::{c_char, c_ulong}, prelude::*, str::CString, - sync::aref::{ARef, AlwaysRefCounted}, - types::Opaque, + sync::aref::{ + ARef, + RefCounted, // + }, + types::{ + AlwaysRefCounted, + Opaque, // + }, // }; #[cfg(CONFIG_CPU_FREQ)] @@ -1041,7 +1047,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 { #[inline] fn inc_ref(&self) { // SAFETY: The existence of a shared reference means that the refcount is nonzero. @@ -1055,6 +1061,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 93a5dfcc1e6f5..a156267bf8bb1 100644 --- a/rust/kernel/owned.rs +++ b/rust/kernel/owned.rs @@ -27,7 +27,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::sync::aref::AlwaysRefCounted) should be implemented. +/// [`RefCounted`](crate::types::RefCounted) should be implemented. /// /// # Examples /// diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 5071cae6543fd..ea9ef99cecb07 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, // }; @@ -481,7 +485,7 @@ unsafe impl device::AsBusDevice for Device impl<'a> crate::dma::Device<'a> 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()) }; @@ -493,6 +497,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..067f68b99e8c5 100644 --- a/rust/kernel/pid_namespace.rs +++ b/rust/kernel/pid_namespace.rs @@ -7,7 +7,14 @@ //! 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 +48,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 +62,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 9b362e0495d32..0ba676445b06d 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -27,6 +27,10 @@ }, of, prelude::*, + sync::aref::{ + AlwaysRefCounted, + RefCounted, // + }, types::Opaque, ThisModule, // }; @@ -518,7 +522,7 @@ pub fn optional_irq_by_name(&self, name: &CStr) -> Result> { impl<'a> crate::dma::Device<'a> 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()) }; @@ -530,6 +534,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/pwm.rs b/rust/kernel/pwm.rs index 6c9d667009ef7..2d1cd74dd98e1 100644 --- a/rust/kernel/pwm.rs +++ b/rust/kernel/pwm.rs @@ -13,7 +13,11 @@ devres, error::{self, to_result}, prelude::*, - sync::aref::{ARef, AlwaysRefCounted}, + sync::aref::{ + ARef, + AlwaysRefCounted, + RefCounted, // + }, types::Opaque, // }; use core::{ @@ -629,7 +633,7 @@ pub fn new<'a>( } // SAFETY: Implements refcounting for `Chip` using the embedded `struct device`. -unsafe impl AlwaysRefCounted for Chip { +unsafe impl RefCounted for Chip { #[inline] fn inc_ref(&self) { // SAFETY: `self.0.get()` points to a valid `pwm_chip` because `self` exists. @@ -647,6 +651,10 @@ unsafe fn dec_ref(obj: NonNull>) { } } +// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef>` from a +// `&Chip`. +unsafe impl AlwaysRefCounted for Chip {} + // SAFETY: `Chip` is a wrapper around `*mut bindings::pwm_chip`. The underlying C // structure's state is managed and synchronized by the kernel's device model // and PWM core locking mechanisms. Therefore, it is safe to move the `Chip` diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs index 3bd5eb8a1a526..ea5a16b8163a6 100644 --- a/rust/kernel/sync/aref.rs +++ b/rust/kernel/sync/aref.rs @@ -11,7 +11,7 @@ //! underlying object, but this refcount is internal to the object. It essentially is a Rust //! implementation of the `get_` and `put_` pattern used in C for reference counting. //! -//! To make use of [`ARef`], `MyType` needs to implement [`AlwaysRefCounted`]. It is a trait +//! To make use of [`ARef`], `MyType` needs to implement [`RefCounted`]. It is a trait //! for accessing the internal reference count of an object of the `MyType` type. //! //! [`Arc`]: crate::sync::Arc @@ -24,11 +24,9 @@ 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 @@ -45,9 +43,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); @@ -60,11 +57,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 @@ -75,7 +88,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, } @@ -84,19 +97,19 @@ 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 {} // Even if `T` is pinned, pointers to `T` can still move. -impl Unpin for ARef {} +impl Unpin 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. @@ -125,12 +138,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) {} /// } @@ -148,7 +161,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. @@ -156,7 +169,7 @@ fn clone(&self) -> Self { } } -impl Deref for ARef { +impl Deref for ARef { type Target = T; fn deref(&self) -> &Self::Target { @@ -173,7 +186,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. @@ -183,19 +196,19 @@ fn drop(&mut self) { impl PartialEq> for ARef where - T: AlwaysRefCounted + PartialEq, - U: AlwaysRefCounted, + T: RefCounted + PartialEq, + U: RefCounted, { #[inline] fn eq(&self, other: &ARef) -> bool { T::eq(&**self, &**other) } } -impl Eq for ARef {} +impl Eq for ARef {} impl PartialEq<&'_ U> for ARef where - T: AlwaysRefCounted + PartialEq, + T: RefCounted + PartialEq, { #[inline] fn eq(&self, other: &&U) -> bool { diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index 38273f4eedb51..6259430b0ca31 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -10,7 +10,12 @@ pid_namespace::PidNamespace, prelude::*, sync::aref::ARef, - types::{NotThreadSafe, Opaque}, + types::{ + AlwaysRefCounted, + NotThreadSafe, + Opaque, + RefCounted, // + }, }; use core::{ ops::Deref, @@ -347,7 +352,7 @@ pub fn group_leader(&self) -> &Task { } // 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. @@ -361,6 +366,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 PartialEq for Task { #[inline] fn eq(&self, other: &Self) -> bool { diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index c41eab0ec983c..5ef763717e59a 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -15,9 +15,15 @@ pub mod for_lt; pub use for_lt::ForLt; -pub use crate::owned::{ - Ownable, - Owned, // +pub use crate::{ + owned::{ + Ownable, + Owned, // + }, + sync::aref::{ + AlwaysRefCounted, + RefCounted, // + }, // }; /// Used to transfer ownership to and from foreign (non-Rust) languages. diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index 7aff0c82d0afc..59350c6b0df2a 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -18,7 +18,10 @@ to_result, // }, prelude::*, - sync::aref::AlwaysRefCounted, + sync::aref::{ + AlwaysRefCounted, + RefCounted, // + }, types::Opaque, ThisModule, // }; @@ -392,7 +395,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 @@ -406,6 +409,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 {} @@ -443,7 +450,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 @@ -457,6 +464,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/workqueue.rs b/rust/kernel/workqueue.rs index 7e253b6f299ce..77673b8ea45fb 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -192,7 +192,7 @@ sync::{ aref::{ ARef, - AlwaysRefCounted, // + RefCounted, // }, Arc, LockClassKey, // @@ -954,7 +954,7 @@ unsafe impl RawDelayedWorkItem for Pin> // implementation of `WorkItemPointer` for `ARef`. unsafe impl WorkItemPointer for ARef where - T: AlwaysRefCounted, + T: RefCounted, T: WorkItem, T: HasWork, { @@ -987,7 +987,7 @@ unsafe impl WorkItemPointer for ARef // requirements of `WorkItemPointer`. unsafe impl RawWorkItem for ARef where - T: AlwaysRefCounted, + T: RefCounted, T: WorkItem, T: HasWork, { @@ -1020,7 +1020,7 @@ unsafe impl RawDelayedWorkItem for ARef where T: WorkItem, T: HasDelayedWork, - T: AlwaysRefCounted, + T: RefCounted, { } -- 2.51.2