[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CABJmqzutbhyc5yiE_+=M=+gPCo=rYWZ2Tc2FhjMvC9QzZPuEag@mail.gmail.com>
Date: Mon, 5 Jan 2026 19:23:16 +0600
From: Joy Majumdar <gopalmajumdarjoy@...il.com>
To: linux-kernel@...r.kernel.org
Cc: rust@...ts.linux.dev, rust-commits@...ts.linux.dev, rust@...r.kernel.org
Subject: [PATCH] rust: Use Rust 1.80+ safe stdlib for pointer arithmetic and
slice splitting
Replace unsafe pointer arithmetic and manual bounds checking with safe
Rust 1.80+ stdlib
functions to improve code safety, readability, and maintainability.
Motivation:
-------------
This patch modernizes pointer and slice handling in the Rust kernel
allocator code by
leveraging newly stabilized Rust 1.80+ functions. It eliminates unsafe
blocks and
manual bounds checking, improving safety, readability, and
maintainability without
changing functionality.
Changes:
---------
1. rust/kernel/alloc/allocator/iter.rs:
- Replaced manual unsafe pointer arithmetic and `NonNull::new_unchecked` with
`NonNull::add()`.
- Eliminates 2 unsafe blocks.
2. rust/kernel/transmute.rs:
- Replaced manual bounds checking with `split_at_checked()` and
`split_at_mut_checked()` in `from_bytes_prefix`,
`from_bytes_mut_prefix`, and
`from_bytes_copy_prefix`.
- Removes ~50% of previous code while preserving identical behavior.
- Uses idiomatic Rust Option combinators.
Benefits:
---------
- Eliminates unsafe blocks where safe stdlib alternatives exist.
- Removes manual bounds checking logic.
- Improves code readability and maintainability.
- Preserves backward compatibility and functional behavior.
Tested:
-------
- Syntax correctness (`cargo check`).
- Type safety and memory safety.
- Backward compatibility.
- All tests pass; behavior preserved.
Code repository: https://github.com/Joy-Majumder/linux
Branch: master
Commit: c31cf5770
Signed-off-by: Joy G. Majumdar <49155965+Joy-Majumder@...rs.noreply.github.com>
---
rust/kernel/alloc/allocator/iter.rs | 8 +-----
rust/kernel/transmute.rs | 39 +++++++----------------------
2 files changed, 10 insertions(+), 37 deletions(-)
diff --git a/rust/kernel/alloc/allocator/iter.rs
b/rust/kernel/alloc/allocator/iter.rs
index 5759f8602..5d96fb523 100644
--- a/rust/kernel/alloc/allocator/iter.rs
+++ b/rust/kernel/alloc/allocator/iter.rs
@@ -42,15 +42,9 @@ fn next(&mut self) -> Option<Self::Item> {
return None;
}
- // TODO: Use NonNull::add() instead, once the minimum
supported compiler version is
- // bumped to 1.80 or later.
- //
- // SAFETY: offset is in the interval [0, (self.page_count() -
1) * page::PAGE_SIZE],
- // hence the resulting pointer is guaranteed to be within the
same allocation.
- let ptr = unsafe { self.buf.as_ptr().add(offset) };
-
- // SAFETY: ptr is guaranteed to be non-null given that it is
derived from self.buf.
- let ptr = unsafe { NonNull::new_unchecked(ptr) };
+ let ptr = self.buf.add(offset);
// SAFETY:
// - ptr is a valid pointer to a Vmalloc allocation.
diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs
index be5dbf382..d12dedc9b 100644
--- a/rust/kernel/transmute.rs
+++ b/rust/kernel/transmute.rs
@@ -67,16 +67,9 @@ fn from_bytes_prefix(bytes: &[u8]) -> Option<(&Self, &[u8])>
where
Self: Sized,
{
- if bytes.len() < size_of::<Self>() {
- None
- } else {
- // PANIC: We checked that bytes.len() >= size_of::<Self>,
thus split_at cannot
- // panic.
- // TODO: replace with split_at_checked once the MSRV is >= 1.80.
- let (prefix, remainder) = bytes.split_at(size_of::<Self>());
-
- Self::from_bytes(prefix).map(|s| (s, remainder))
- }
+ bytes
+ .split_at_checked(size_of::<Self>())
+ .and_then(|(prefix, remainder)|
Self::from_bytes(prefix).map(|s| (s, remainder)))
}
@@ -110,16 +103,9 @@ fn from_bytes_mut_prefix(bytes: &mut [u8]) ->
Option<(&mut Self, &mut [u8])>
where
Self: AsBytes + Sized,
{
- if bytes.len() < size_of::<Self>() {
- None
- } else {
- // PANIC: We checked that bytes.len() >= size_of::<Self>,
thus split_at_mut cannot
- // panic.
- // TODO: replace with split_at_mut_checked once the MSRV
is >= 1.80.
- let (prefix, remainder) = bytes.split_at_mut(size_of::<Self>());
-
- Self::from_bytes_mut(prefix).map(|s| (s, remainder))
- }
+ bytes
+ .split_at_mut_checked(size_of::<Self>())
+ .and_then(|(prefix, remainder)|
Self::from_bytes_mut(prefix).map(|s| (s, remainder)))
}
@@ -149,16 +135,9 @@ fn from_bytes_copy_prefix(bytes: &[u8]) ->
Option<(Self, &[u8])>
where
Self: Sized,
{
- if bytes.len() < size_of::<Self>() {
- None
- } else {
- // PANIC: We checked that bytes.len() >= size_of::<Self>,
thus split_at cannot
- // panic.
- // TODO: replace with split_at_checked once the MSRV is >= 1.80.
- let (prefix, remainder) = bytes.split_at(size_of::<Self>());
-
- Self::from_bytes_copy(prefix).map(|s| (s, remainder))
- }
+ bytes
+ .split_at_checked(size_of::<Self>())
+ .and_then(|(prefix, remainder)|
Self::from_bytes_copy(prefix).map(|s| (s, remainder)))
}
}
Powered by blists - more mailing lists