public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: David Rheinsberg <david@readahead.eu>
To: rust-for-linux@vger.kernel.org
Cc: teg@jklm.no, Miguel Ojeda <ojeda@kernel.org>,
	David Rheinsberg <david@readahead.eu>
Subject: [RFC 08/16] bus1/util: add basic utilities
Date: Tue, 31 Mar 2026 21:03:00 +0200	[thread overview]
Message-ID: <20260331190308.141622-9-david@readahead.eu> (raw)
In-Reply-To: <20260331190308.141622-1-david@readahead.eu>

Import some basic utility helpers. They come with documentation and
should be self-explanatory.

Some helpers will become obsolete, once the MSRV is bumped. This is
noted in the documentation.

Signed-off-by: David Rheinsberg <david@readahead.eu>
---
 ipc/bus1/lib.rs      |  2 +
 ipc/bus1/util/mod.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 ipc/bus1/util/mod.rs

diff --git a/ipc/bus1/lib.rs b/ipc/bus1/lib.rs
index 7c3364651638..a7e7a99086c2 100644
--- a/ipc/bus1/lib.rs
+++ b/ipc/bus1/lib.rs
@@ -4,6 +4,8 @@
 //! This is the in-kernel implementation of the Bus1 communication system in
 //! rust. Any user-space API is outside the scope of this module.
 
+pub mod util;
+
 #[allow(
     dead_code,
     missing_docs,
diff --git a/ipc/bus1/util/mod.rs b/ipc/bus1/util/mod.rs
new file mode 100644
index 000000000000..4dd08c04eec6
--- /dev/null
+++ b/ipc/bus1/util/mod.rs
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+//! # Utility library
+//!
+//! This module provides utilities that can be used independently of the core
+//! module.
+
+use kernel::prelude::*;
+use kernel::sync::{Arc, ArcBorrow};
+
+/// Convert an Arc to its pinned version.
+///
+/// All [`Arc`] instances are unconditionally pinned. It is always safe to
+/// convert from their unpinned variant to their pinned variant.
+///
+/// Most kernel APIs just use a plain [`Arc`], even if they rely on pinning.
+/// If another API needs a `Pin<T>`, this converter can provide it for [`Arc`],
+/// even though most other kernel APIs do not use `Pin<Arc<T>>`.
+pub fn arc_pin<T>(v: Arc<T>) -> Pin<Arc<T>> {
+    // SAFETY: `Arc<T>` guarantees its target is pinned.
+    unsafe { Pin::new_unchecked(v) }
+}
+
+/// Convert an Arc to its unpinned version.
+///
+/// All [`Arc`] instances are unconditionally pinned. It is always safe to
+/// convert from their pinned variant to their unpinned variant.
+///
+/// Most kernel APIs just use a plain [`Arc`], even if they rely on pinning.
+/// This converter allows getting an [`Arc`] if some other API returned a
+/// generic `Pin<T>` with `T = Arc<U>`.
+pub fn arc_unpin<T>(v: Pin<Arc<T>>) -> Arc<T> {
+    // SAFETY: `Arc<T>` guarantees its target is pinned, even if not wrapped.
+    unsafe { Pin::into_inner_unchecked(v) }
+}
+
+/// Convert an ArcBorrow to its pinned version.
+///
+/// All [`Arc`] instances are unconditionally pinned. It is always safe to
+/// convert from their unpinned variant to their pinned variant.
+pub fn arc_borrow_pin<T>(v: ArcBorrow<'_, T>) -> Pin<ArcBorrow<'_, T>> {
+    // SAFETY: `Arc<T>` guarantees its target is pinned.
+    unsafe { Pin::new_unchecked(v) }
+}
+
+/// Create a [`NonNull`] from a reference.
+///
+/// This is a backport of [`core::ptr::NonNull::from_ref()`].
+pub fn nonnull_from_ref<T: ?Sized>(v: &T) -> core::ptr::NonNull<T> {
+    // SAFETY: A reference cannot be NULL.
+    unsafe { core::ptr::NonNull::new_unchecked(core::ptr::from_ref(v).cast_mut()) }
+}
+
+/// Create a [`NonNull`] from a reference.
+///
+/// This is a backport of [`core::ptr::NonNull::from_mut()`].
+pub fn nonnull_from_mut<T: ?Sized>(v: &mut T) -> core::ptr::NonNull<T> {
+    // SAFETY: A reference cannot be NULL.
+    unsafe { core::ptr::NonNull::new_unchecked(v) }
+}
+
+/// Return the memory address part of a pointer without exposing provenance.
+///
+/// This returns the same value as an `as usize` cast. However, this function
+/// is meant to not expose provenance, and rather behave like
+/// `<*mut T>::addr()`. Unfortunately, the latter requires an MSRV of 1.84,
+/// which is not yet available upstream. Until then, this serves as a
+/// replacement.
+pub fn ptr_addr<T: ?Sized>(v: *const T) -> usize {
+    // Simply expose the provenance until. A transmute would avoid the
+    // exposition, but is not a stable API.
+    v.cast::<()>() as usize
+}
+
+/// Compare two pointers.
+///
+/// This is equivalent to `<*const T as Ord>::cmp()`. Unlike the trait-based
+/// solution, this has fixed pointer types and thus can be called with
+/// references, which are then coerced to pointers.
+///
+/// This serves the same purpose as `core::ptr::eq()`, but for `Ord` rather
+/// than `Eq`.
+pub fn ptr_cmp<T: ?Sized>(a: *const T, b: *const T) -> core::cmp::Ordering {
+    // Even though `PartialOrd for *mut T` documents that it uses
+    // `<*mut T>::addr()` for comparisons, clippy still warns about it. Cast
+    // to `()` to ensure metadata is ignored.
+    a.cast::<()>().cmp(&b.cast::<()>())
+}
-- 
2.53.0


  parent reply	other threads:[~2026-03-31 19:05 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31 19:02 [RFC 00/16] bus1: Capability-based IPC for Linux David Rheinsberg
2026-03-31 19:02 ` [RFC 01/16] rust/sync: add LockedBy::access_mut_unchecked() David Rheinsberg
2026-03-31 19:29   ` Miguel Ojeda
2026-03-31 19:02 ` [RFC 02/16] rust/sync: add Arc::drop_unless_unique() David Rheinsberg
2026-03-31 19:02 ` [RFC 03/16] rust/alloc: add Vec::into_boxed_slice() David Rheinsberg
2026-03-31 19:28   ` Miguel Ojeda
2026-03-31 21:10   ` Gary Guo
2026-03-31 22:07   ` Danilo Krummrich
2026-04-01  9:28     ` David Rheinsberg
2026-03-31 19:02 ` [RFC 04/16] rust/error: add EXFULL, EBADRQC, EDQUOT, ENOTRECOVERABLE David Rheinsberg
2026-03-31 19:02 ` [RFC 05/16] bus1: add module scaffolding David Rheinsberg
2026-03-31 19:02 ` [RFC 06/16] bus1: add the user-space API David Rheinsberg
2026-03-31 19:02 ` [RFC 07/16] bus1: add man-page David Rheinsberg
2026-04-01 16:30   ` Jonathan Corbet
2026-04-01 18:01     ` David Rheinsberg
2026-04-01 18:06       ` David Rheinsberg
2026-04-04 15:30   ` Thomas Meyer
2026-03-31 19:03 ` David Rheinsberg [this message]
2026-03-31 19:35   ` [RFC 08/16] bus1/util: add basic utilities Miguel Ojeda
2026-04-01 11:05     ` David Rheinsberg
2026-04-01 11:25       ` Miguel Ojeda
2026-03-31 19:03 ` [RFC 09/16] bus1/util: add field projections David Rheinsberg
2026-03-31 19:38   ` Miguel Ojeda
2026-03-31 19:03 ` [RFC 10/16] bus1/util: add IntoDeref/FromDeref David Rheinsberg
2026-03-31 19:44   ` Miguel Ojeda
2026-03-31 19:03 ` [RFC 11/16] bus1/util: add intrusive data-type helpers David Rheinsberg
2026-03-31 19:03 ` [RFC 12/16] bus1/util: add intrusive single linked lists David Rheinsberg
2026-03-31 19:03 ` [RFC 13/16] bus1/util: add intrusive rb-tree David Rheinsberg
2026-03-31 19:43   ` Miguel Ojeda
2026-03-31 19:03 ` [RFC 14/16] bus1/acct: add resouce accounting David Rheinsberg
2026-03-31 19:03 ` [RFC 15/16] bus1: introduce peers, handles, and nodes David Rheinsberg
2026-03-31 19:03 ` [RFC 16/16] bus1: implement the uapi David Rheinsberg
2026-03-31 19:46 ` [RFC 00/16] bus1: Capability-based IPC for Linux Miguel Ojeda

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=20260331190308.141622-9-david@readahead.eu \
    --to=david@readahead.eu \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=teg@jklm.no \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox