From: Andreas Hindborg <a.hindborg@kernel.org>
To: "Miguel Ojeda" <ojeda@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Dave Ertman" <david.m.ertman@intel.com>,
"Ira Weiny" <ira.weiny@intel.com>,
"Leon Romanovsky" <leon@kernel.org>,
"Paul Moore" <paul@paul-moore.com>,
"Serge Hallyn" <sergeh@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Christian Brauner" <brauner@kernel.org>,
"Jan Kara" <jack@suse.cz>,
"Igor Korotin" <igor.korotin.linux@gmail.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
"Viresh Kumar" <vireshk@kernel.org>, "Nishanth Menon" <nm@ti.com>,
"Stephen Boyd" <sboyd@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Vlastimil Babka" <vbabka@suse.cz>,
"Uladzislau Rezki" <urezki@gmail.com>,
"Boqun Feng" <boqun@kernel.org>
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 <a.hindborg@kernel.org>,
Asahi Lina <lina+kernel@asahilina.net>,
Asahi Lina <lina+kernel@asahilina.net>
Subject: [PATCH v16 08/10] rust: page: convert to `Ownable`
Date: Tue, 24 Feb 2026 12:18:03 +0100 [thread overview]
Message-ID: <20260224-unique-ref-v16-8-c21afcb118d3@kernel.org> (raw)
In-Reply-To: <20260224-unique-ref-v16-0-c21afcb118d3@kernel.org>
From: Asahi Lina <lina+kernel@asahilina.net>
This allows Page references to be returned as borrowed references,
without necessarily owning the struct page.
Signed-off-by: Asahi Lina <lina@asahilina.net>
[ Andreas: Fix formatting and add a safety comment. ]
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
rust/kernel/page.rs | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/rust/kernel/page.rs b/rust/kernel/page.rs
index bf3bed7e2d3fe..e21f02ae47b72 100644
--- a/rust/kernel/page.rs
+++ b/rust/kernel/page.rs
@@ -10,6 +10,11 @@
bindings,
error::code::*,
error::Result,
+ types::{
+ Opaque,
+ Ownable,
+ Owned, //
+ },
uaccess::UserSliceReader, //
};
use core::{
@@ -83,7 +88,7 @@ pub const fn page_align(addr: usize) -> usize {
///
/// [`VBox`]: kernel::alloc::VBox
/// [`Vmalloc`]: kernel::alloc::allocator::Vmalloc
-pub struct BorrowedPage<'a>(ManuallyDrop<Page>, PhantomData<&'a Page>);
+pub struct BorrowedPage<'a>(ManuallyDrop<NonNull<Page>>, PhantomData<&'a Page>);
impl<'a> BorrowedPage<'a> {
/// Constructs a [`BorrowedPage`] from a raw pointer to a `struct page`.
@@ -93,7 +98,9 @@ impl<'a> BorrowedPage<'a> {
/// - `ptr` must point to a valid `bindings::page`.
/// - `ptr` must remain valid for the entire lifetime `'a`.
pub unsafe fn from_raw(ptr: NonNull<bindings::page>) -> Self {
- let page = Page { page: ptr };
+ let page: NonNull<Page> =
+ // SAFETY: By function safety requirements `ptr` is non null.
+ unsafe { NonNull::new_unchecked(ptr.as_ptr().cast()) };
// INVARIANT: The safety requirements guarantee that `ptr` is valid for the entire lifetime
// `'a`.
@@ -105,7 +112,8 @@ impl<'a> Deref for BorrowedPage<'a> {
type Target = Page;
fn deref(&self) -> &Self::Target {
- &self.0
+ // SAFETY: By type invariant `self.0` is convertible to a reference for `'a`.
+ unsafe { self.0.as_ref() }
}
}
@@ -126,8 +134,9 @@ pub trait AsPageIter {
/// # Invariants
///
/// The pointer is valid, and has ownership over the page.
+#[repr(transparent)]
pub struct Page {
- page: NonNull<bindings::page>,
+ page: Opaque<bindings::page>,
}
// SAFETY: Pages have no logic that relies on them staying on a given thread, so moving them across
@@ -161,19 +170,20 @@ impl Page {
/// # Ok::<(), kernel::alloc::AllocError>(())
/// ```
#[inline]
- pub fn alloc_page(flags: Flags) -> Result<Self, AllocError> {
+ pub fn alloc_page(flags: Flags) -> Result<Owned<Self>, AllocError> {
// SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it
// is always safe to call this method.
let page = unsafe { bindings::alloc_pages(flags.as_raw(), 0) };
let page = NonNull::new(page).ok_or(AllocError)?;
- // INVARIANT: We just successfully allocated a page, so we now have ownership of the newly
- // allocated page. We transfer that ownership to the new `Page` object.
- Ok(Self { page })
+ // SAFETY: We just successfully allocated a page, so we now have ownership of the newly
+ // allocated page. We transfer that ownership to the new `Owned<Page>` object.
+ // Since `Page` is transparent, we can cast the pointer directly.
+ Ok(unsafe { Owned::from_raw(page.cast()) })
}
/// Returns a raw pointer to the page.
pub fn as_ptr(&self) -> *mut bindings::page {
- self.page.as_ptr()
+ Opaque::cast_into(&self.page)
}
/// Get the node id containing this page.
@@ -348,10 +358,12 @@ pub unsafe fn copy_from_user_slice_raw(
}
}
-impl Drop for Page {
+impl Ownable for Page {
#[inline]
- fn drop(&mut self) {
- // SAFETY: By the type invariants, we have ownership of the page and can free it.
- unsafe { bindings::__free_pages(self.page.as_ptr(), 0) };
+ unsafe fn release(&mut self) {
+ let ptr: *mut Self = self;
+ // SAFETY: By the function safety requirements, we have ownership of the page and can free
+ // it. Since Page is transparent, we can cast the raw pointer directly.
+ unsafe { bindings::__free_pages(ptr.cast(), 0) };
}
}
--
2.51.2
next prev parent reply other threads:[~2026-02-24 11:20 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 11:17 [PATCH v16 00/10] rust: add `Ownable` trait and `Owned` type Andreas Hindborg
2026-02-24 11:17 ` [PATCH v16 01/10] rust: alloc: add `KBox::into_nonnull` Andreas Hindborg
2026-03-01 13:26 ` Gary Guo
2026-03-01 16:34 ` Andreas Hindborg
2026-03-01 19:25 ` Gary Guo
2026-03-01 19:59 ` Benno Lossin
2026-03-01 20:47 ` Gary Guo
2026-03-02 7:18 ` Andreas Hindborg
2026-03-02 12:32 ` Miguel Ojeda
2026-02-24 11:17 ` [PATCH v16 02/10] rust: types: Add Ownable/Owned types Andreas Hindborg
2026-02-24 11:17 ` [PATCH v16 03/10] rust: rename `AlwaysRefCounted` to `RefCounted` Andreas Hindborg
2026-02-24 11:17 ` [PATCH v16 04/10] rust: Add missing SAFETY documentation for `ARef` example Andreas Hindborg
2026-02-24 11:18 ` [PATCH v16 05/10] rust: aref: update formatting of use statements Andreas Hindborg
2026-02-24 11:18 ` [PATCH v16 06/10] rust: Add `OwnableRefCounted` Andreas Hindborg
2026-02-24 11:18 ` [PATCH v16 07/10] rust: page: update formatting of `use` statements Andreas Hindborg
2026-02-24 11:18 ` Andreas Hindborg [this message]
2026-02-24 11:18 ` [PATCH v16 09/10] rust: implement `ForeignOwnable` for `Owned` Andreas Hindborg
2026-02-24 11:18 ` [PATCH v16 10/10] rust: page: add `from_raw()` Andreas Hindborg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260224-unique-ref-v16-8-c21afcb118d3@kernel.org \
--to=a.hindborg@kernel.org \
--cc=Liam.Howlett@oracle.com \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=brauner@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=david.m.ertman@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=igor.korotin.linux@gmail.com \
--cc=ira.weiny@intel.com \
--cc=jack@suse.cz \
--cc=kwilczynski@kernel.org \
--cc=leon@kernel.org \
--cc=lina+kernel@asahilina.net \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=lossin@kernel.org \
--cc=nm@ti.com \
--cc=ojeda@kernel.org \
--cc=paul@paul-moore.com \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sboyd@kernel.org \
--cc=sergeh@kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=urezki@gmail.com \
--cc=vbabka@suse.cz \
--cc=vireshk@kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.