* [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut`
@ 2024-11-20 11:45 Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
` (7 more replies)
0 siblings, 8 replies; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:45 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein,
Martin Rodriguez Reboredo
This is a re-submission of Alice's patch[0]. The leading commits are
intended to improve the consistency and ergonomics of `ForeignOwnable`,
and to split out the code movement originally included in the patch.
`ForeignOwnable::borrow_mut` is a dependency of the memory backing
feature of `rnull`, the Rust null block driver.
Link: https://lore.kernel.org/all/20230710074642.683831-1-aliceryhl@google.com/T/#u [0]
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
Changes in v6:
- Rebase on linux-next, resolve conflict with f893691e7426 ("rust: miscdevice: add base miscdevice abstraction") [1]
- Link: https://lore.kernel.org/all/20241001-b4-miscdevice-v2-2-330d760041fa@google.com/ [1]
- Link to v5: https://lore.kernel.org/r/20241115-borrow-mut-v5-0-86204b249667@gmail.com
Changes in v5:
- Rebase on d072acda4862 ("rust: use custom FFI integer types") [0]
- Link: https://lore.kernel.org/all/20240913213041.395655-4-gary@garyguo.net/ [0]
- Link to v4: https://lore.kernel.org/r/20241110-borrow-mut-v4-0-053976068215@gmail.com
Changes in v4:
- Remove (another) superfluous `cast_const()`. (Alice Ryhl)
- Link to v3: https://lore.kernel.org/r/20241108-borrow-mut-v3-0-b7144945714e@gmail.com
Changes in v3:
- Remove superfluous `cast_const()`. (Alice Ryhl)
- Correct SoB placement. (Alice Ryhl)
- Mention `as` cast removal. (Miguel Ojeda)
- Link to v2: https://lore.kernel.org/r/20241104-borrow-mut-v2-0-de650678648d@gmail.com
Changes in v2:
- Call out ordering inconsistency in commit message.
- Restore pointer type ascriptionin Arc. (Andreas Hindborg)
- Remove most reduction of unsafe blocks. (Andreas Hindborg)
- Lift splitting of unsafe block into separate patch.
- Link to v1: https://lore.kernel.org/r/20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com
---
Alice Ryhl (1):
rust: add improved version of `ForeignOwnable::borrow_mut`
Tamir Duberstein (5):
rust: arc: use `NonNull::new_unchecked`
rust: types: avoid `as` casts
rust: arc: split unsafe block, add missing comment
rust: change `ForeignOwnable` pointer to mut
rust: reorder `ForeignOwnable` items
rust/kernel/alloc/kbox.rs | 41 ++++++++++++++++-----
rust/kernel/miscdevice.rs | 2 +-
rust/kernel/sync/arc.rs | 42 ++++++++++++++-------
rust/kernel/types.rs | 93 +++++++++++++++++++++++++++++++++++------------
4 files changed, 130 insertions(+), 48 deletions(-)
---
base-commit: 7510705aa41f7891c84dbb37965f492f09ae2077
change-id: 20241030-borrow-mut-75f181feef4c
Best regards,
--
Tamir Duberstein <tamird@gmail.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v6 1/6] rust: arc: use `NonNull::new_unchecked`
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 2/6] rust: types: avoid `as` casts Tamir Duberstein
` (6 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein
There is no need to check (and panic on violations of) the safety
requirements on `ForeignOwnable` functions. Avoiding the check is
consistent with the implementation of `ForeignOwnable` for `Box`.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/sync/arc.rs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index fa4509406ee909ca0677b78d5ece966089ce6366..b4e492dd712137c7c39e3de3d39c0c833944828c 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -337,9 +337,9 @@ fn into_foreign(self) -> *const crate::ffi::c_void {
}
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
- // By the safety requirement of this function, we know that `ptr` came from
- // a previous call to `Arc::into_foreign`.
- let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap();
+ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
+ // call to `Self::into_foreign`.
+ let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
// SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
// for the lifetime of the returned value.
@@ -347,10 +347,14 @@ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
}
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
+ // call to `Self::into_foreign`.
+ let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
+
// SAFETY: By the safety requirement of this function, we know that `ptr` came from
// a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
// holds a reference count increment that is transferrable to us.
- unsafe { Self::from_inner(NonNull::new(ptr as _).unwrap()) }
+ unsafe { Self::from_inner(inner) }
}
}
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v6 2/6] rust: types: avoid `as` casts
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2025-01-13 13:15 ` Danilo Krummrich
2024-11-20 11:46 ` [PATCH v6 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
` (5 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein
Replace `as` casts with `cast{,_mut}` calls which are a bit safer.
In one instance, remove an unnecessary `as` cast without replacement.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/alloc/kbox.rs | 8 ++++----
rust/kernel/sync/arc.rs | 9 +++++----
rust/kernel/types.rs | 2 +-
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 9ce414361c2c6dd8eea09b11041f6c307cbc7864..3f0b04609bd487e3f50247f9f1abd5394b749c7e 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -356,13 +356,13 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
type Borrowed<'a> = &'a T;
fn into_foreign(self) -> *const crate::ffi::c_void {
- Box::into_raw(self) as _
+ Box::into_raw(self).cast()
}
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Box::from_raw(ptr as _) }
+ unsafe { Box::from_raw(ptr.cast_mut().cast()) }
}
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
@@ -380,13 +380,13 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
fn into_foreign(self) -> *const crate::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
- Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
+ Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
}
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
+ unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast_mut().cast())) }
}
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index b4e492dd712137c7c39e3de3d39c0c833944828c..50645660a9c33cb121ee1b2469003b325000d840 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -201,10 +201,11 @@ pub fn new(contents: T, flags: Flags) -> Result<Self, AllocError> {
};
let inner = KBox::new(value, flags)?;
+ let inner = KBox::leak(inner).into();
// SAFETY: We just created `inner` with a reference count of 1, which is owned by the new
// `Arc` object.
- Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) })
+ Ok(unsafe { Self::from_inner(inner) })
}
}
@@ -333,13 +334,13 @@ impl<T: 'static> ForeignOwnable for Arc<T> {
type Borrowed<'a> = ArcBorrow<'a, T>;
fn into_foreign(self) -> *const crate::ffi::c_void {
- ManuallyDrop::new(self).ptr.as_ptr() as _
+ ManuallyDrop::new(self).ptr.as_ptr().cast()
}
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
+ let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
// SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
// for the lifetime of the returned value.
@@ -349,7 +350,7 @@ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
+ let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
// SAFETY: By the safety requirement of this function, we know that `ptr` came from
// a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index ec6457bb3084ae327c38ba4ba79b1601aef38244..318d2140470a90568100f86fd8c6d8084031f556 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -434,7 +434,7 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
/// }
///
/// let mut data = Empty {};
- /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
+ /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
/// # // SAFETY: TODO.
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v6 3/6] rust: arc: split unsafe block, add missing comment
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 2/6] rust: types: avoid `as` casts Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
` (4 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein
The new SAFETY comment style is taken from existing comments in `deref`
and `drop.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/sync/arc.rs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 50645660a9c33cb121ee1b2469003b325000d840..a11f267ce5d40b987f1f3c459271e5317ea0bae8 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -377,10 +377,14 @@ fn as_ref(&self) -> &T {
impl<T: ?Sized> Clone for Arc<T> {
fn clone(&self) -> Self {
+ // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
+ // safe to dereference it.
+ let refcount = unsafe { self.ptr.as_ref() }.refcount.get();
+
// INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero.
// SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
// safe to increment the refcount.
- unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) };
+ unsafe { bindings::refcount_inc(refcount) };
// SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`.
unsafe { Self::from_inner(self.ptr) }
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (2 preceding siblings ...)
2024-11-20 11:46 ` [PATCH v6 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2025-01-13 13:15 ` Danilo Krummrich
2024-11-20 11:46 ` [PATCH v6 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
` (3 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein
It is slightly more convenient to operate on mut pointers, and this also
properly conveys the desired ownership semantics of the trait.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/alloc/kbox.rs | 16 ++++++++--------
rust/kernel/miscdevice.rs | 2 +-
rust/kernel/sync/arc.rs | 10 +++++-----
rust/kernel/types.rs | 14 +++++++-------
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 3f0b04609bd487e3f50247f9f1abd5394b749c7e..e00c14053efbfb08d053e0f0b11247fa25d9d516 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -355,17 +355,17 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
{
type Borrowed<'a> = &'a T;
- fn into_foreign(self) -> *const crate::ffi::c_void {
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
Box::into_raw(self).cast()
}
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Box::from_raw(ptr.cast_mut().cast()) }
+ unsafe { Box::from_raw(ptr.cast()) }
}
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
// SAFETY: The safety requirements of this method ensure that the object remains alive and
// immutable for the duration of 'a.
unsafe { &*ptr.cast() }
@@ -378,18 +378,18 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
{
type Borrowed<'a> = Pin<&'a T>;
- fn into_foreign(self) -> *const crate::ffi::c_void {
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
}
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast_mut().cast())) }
+ unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
}
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
// SAFETY: The safety requirements for this function ensure that the object is still alive,
// so it is safe to dereference the raw pointer.
// The safety requirements of `from_foreign` also ensure that the object remains alive for
diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index 7e2a79b3ae263659b7e0781c05cb130d10c8accb..e58807ad28dc644fa384e9c1fb41fd6e53abea7a 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -193,7 +193,7 @@ impl<T: MiscDevice> VtableHelper<T> {
};
// SAFETY: The open call of a file owns the private data.
- unsafe { (*file).private_data = ptr.into_foreign().cast_mut() };
+ unsafe { (*file).private_data = ptr.into_foreign() };
0
}
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index a11f267ce5d40b987f1f3c459271e5317ea0bae8..01d85da799d77127fc99a9b270b8a7b1ef435b6f 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -333,24 +333,24 @@ pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> {
impl<T: 'static> ForeignOwnable for Arc<T> {
type Borrowed<'a> = ArcBorrow<'a, T>;
- fn into_foreign(self) -> *const crate::ffi::c_void {
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
ManuallyDrop::new(self).ptr.as_ptr().cast()
}
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
+ let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
// SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
// for the lifetime of the returned value.
unsafe { ArcBorrow::new(inner) }
}
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
+ let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
// SAFETY: By the safety requirement of this function, we know that `ptr` came from
// a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index 318d2140470a90568100f86fd8c6d8084031f556..f9b398ee31fd5303f0224995f51d314a0c4ecbf2 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -29,7 +29,7 @@ pub trait ForeignOwnable: Sized {
/// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
/// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
/// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
- fn into_foreign(self) -> *const crate::ffi::c_void;
+ fn into_foreign(self) -> *mut crate::ffi::c_void;
/// Borrows a foreign-owned object.
///
@@ -37,7 +37,7 @@ pub trait ForeignOwnable: Sized {
///
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>;
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
/// Converts a foreign-owned object back to a Rust-owned one.
///
@@ -47,7 +47,7 @@ pub trait ForeignOwnable: Sized {
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
/// this object must have been dropped.
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self;
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self;
/// Tries to convert a foreign-owned object back to a Rust-owned one.
///
@@ -58,7 +58,7 @@ pub trait ForeignOwnable: Sized {
///
/// `ptr` must either be null or satisfy the safety requirements for
/// [`ForeignOwnable::from_foreign`].
- unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
+ unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
if ptr.is_null() {
None
} else {
@@ -72,13 +72,13 @@ unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
impl ForeignOwnable for () {
type Borrowed<'a> = ();
- fn into_foreign(self) -> *const crate::ffi::c_void {
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
}
- unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {}
+ unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
- unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {}
+ unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v6 5/6] rust: reorder `ForeignOwnable` items
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (3 preceding siblings ...)
2024-11-20 11:46 ` [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (2 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein
`{into,from}_foreign` before `borrow` is slightly more logical.
This removes an inconsistency with `kbox.rs` which already uses this
ordering.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/sync/arc.rs | 18 +++++++++---------
rust/kernel/types.rs | 20 ++++++++++----------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 01d85da799d77127fc99a9b270b8a7b1ef435b6f..1d26c309d21db53f1fc769562c2afb4e881c3b5b 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -337,25 +337,25 @@ fn into_foreign(self) -> *mut crate::ffi::c_void {
ManuallyDrop::new(self).ptr.as_ptr().cast()
}
- unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
- // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
- // for the lifetime of the returned value.
- unsafe { ArcBorrow::new(inner) }
+ // SAFETY: By the safety requirement of this function, we know that `ptr` came from
+ // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
+ // holds a reference count increment that is transferrable to us.
+ unsafe { Self::from_inner(inner) }
}
- unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
- // SAFETY: By the safety requirement of this function, we know that `ptr` came from
- // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
- // holds a reference count increment that is transferrable to us.
- unsafe { Self::from_inner(inner) }
+ // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
+ // for the lifetime of the returned value.
+ unsafe { ArcBorrow::new(inner) }
}
}
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index f9b398ee31fd5303f0224995f51d314a0c4ecbf2..af316e291908123407f08c665c91113a666fc593 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -31,14 +31,6 @@ pub trait ForeignOwnable: Sized {
/// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
fn into_foreign(self) -> *mut crate::ffi::c_void;
- /// Borrows a foreign-owned object.
- ///
- /// # Safety
- ///
- /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
- /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
- unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
-
/// Converts a foreign-owned object back to a Rust-owned one.
///
/// # Safety
@@ -67,6 +59,14 @@ unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
unsafe { Some(Self::from_foreign(ptr)) }
}
}
+
+ /// Borrows a foreign-owned object.
+ ///
+ /// # Safety
+ ///
+ /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
+ /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
}
impl ForeignOwnable for () {
@@ -76,9 +76,9 @@ fn into_foreign(self) -> *mut crate::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
}
- unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
-
unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
+
+ unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (4 preceding siblings ...)
2024-11-20 11:46 ` [PATCH v6 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
@ 2024-11-20 11:46 ` Tamir Duberstein
2025-01-13 13:18 ` Danilo Krummrich
2025-01-13 12:09 ` [PATCH v6 0/6] " Miguel Ojeda
2025-01-13 23:52 ` Miguel Ojeda
7 siblings, 1 reply; 15+ messages in thread
From: Tamir Duberstein @ 2024-11-20 11:46 UTC (permalink / raw)
To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Tamir Duberstein,
Martin Rodriguez Reboredo
From: Alice Ryhl <aliceryhl@google.com>
Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
that was intended to provide mutable access to the inner value. However,
the method accidentally made it possible to change the address of the
object being modified, which usually isn't what we want. (And when we
want that, it can be done by calling `from_foreign` and `into_foreign`,
like how the old `borrow_mut` was implemented.)
In this patch, we introduce an alternate definition of `borrow_mut` that
solves the previous problem. Conceptually, given a pointer type `P` that
implements `ForeignOwnable`, the `borrow_mut` method gives you the same
kind of access as an `&mut P` would, except that it does not let you
change the pointer `P` itself.
This is analogous to how the existing `borrow` method provides the same
kind of access to the inner value as an `&P`.
Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
immutable access to the inner `T`. This is because mutable references
assume exclusive access, but there might be other handles to the same
reference counted value, so the access isn't exclusive. The `Arc` type
implements this by making `borrow_mut` return the same type as `borrow`.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/alloc/kbox.rs | 21 ++++++++++++++
rust/kernel/sync/arc.rs | 7 +++++
rust/kernel/types.rs | 71 ++++++++++++++++++++++++++++++++++++++---------
3 files changed, 86 insertions(+), 13 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index e00c14053efbfb08d053e0f0b11247fa25d9d516..4ffc4e1b22b2b7c2ea8e8ed5b7f7a8534625249f 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -354,6 +354,7 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
A: Allocator,
{
type Borrowed<'a> = &'a T;
+ type BorrowedMut<'a> = &'a mut T;
fn into_foreign(self) -> *mut crate::ffi::c_void {
Box::into_raw(self).cast()
@@ -370,6 +371,13 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
// immutable for the duration of 'a.
unsafe { &*ptr.cast() }
}
+
+ unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> &'a mut T {
+ let ptr = ptr.cast();
+ // SAFETY: The safety requirements of this method ensure that the pointer is valid and that
+ // nothing else will access the value for the duration of 'a.
+ unsafe { &mut *ptr }
+ }
}
impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
@@ -377,6 +385,7 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
A: Allocator,
{
type Borrowed<'a> = Pin<&'a T>;
+ type BorrowedMut<'a> = Pin<&'a mut T>;
fn into_foreign(self) -> *mut crate::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
@@ -399,6 +408,18 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
unsafe { Pin::new_unchecked(r) }
}
+
+ unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> Pin<&'a mut T> {
+ let ptr = ptr.cast();
+ // SAFETY: The safety requirements for this function ensure that the object is still alive,
+ // so it is safe to dereference the raw pointer.
+ // The safety requirements of `from_foreign` also ensure that the object remains alive for
+ // the lifetime of the returned value.
+ let r = unsafe { &mut *ptr };
+
+ // SAFETY: This pointer originates from a `Pin<Box<T>>`.
+ unsafe { Pin::new_unchecked(r) }
+ }
}
impl<T, A> Deref for Box<T, A>
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 1d26c309d21db53f1fc769562c2afb4e881c3b5b..eb5cd8b360a3507a527978aaf96dbc3a80d4ae2c 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -332,6 +332,7 @@ pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> {
impl<T: 'static> ForeignOwnable for Arc<T> {
type Borrowed<'a> = ArcBorrow<'a, T>;
+ type BorrowedMut<'a> = Self::Borrowed<'a>;
fn into_foreign(self) -> *mut crate::ffi::c_void {
ManuallyDrop::new(self).ptr.as_ptr().cast()
@@ -357,6 +358,12 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
// for the lifetime of the returned value.
unsafe { ArcBorrow::new(inner) }
}
+
+ unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> {
+ // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
+ // requirements for `borrow`.
+ unsafe { Self::borrow(ptr) }
+ }
}
impl<T: ?Sized> Deref for Arc<T> {
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index af316e291908123407f08c665c91113a666fc593..0dfaf45a755c7ce702027918e5fd3e97c407fda4 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -19,26 +19,33 @@
/// This trait is meant to be used in cases when Rust objects are stored in C objects and
/// eventually "freed" back to Rust.
pub trait ForeignOwnable: Sized {
- /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
- /// [`ForeignOwnable::from_foreign`].
+ /// Type used to immutably borrow a value that is currently foreign-owned.
type Borrowed<'a>;
+ /// Type used to mutably borrow a value that is currently foreign-owned.
+ type BorrowedMut<'a>;
+
/// Converts a Rust-owned object to a foreign-owned one.
///
/// The foreign representation is a pointer to void. There are no guarantees for this pointer.
/// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
- /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
- /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
+ /// any way except for [`from_foreign`], [`try_from_foreign`], [`borrow`], or [`borrow_mut`] can
+ /// result in undefined behavior.
+ ///
+ /// [`from_foreign`]: Self::from_foreign
+ /// [`try_from_foreign`]: Self::try_from_foreign
+ /// [`borrow`]: Self::borrow
+ /// [`borrow_mut`]: Self::borrow_mut
fn into_foreign(self) -> *mut crate::ffi::c_void;
/// Converts a foreign-owned object back to a Rust-owned one.
///
/// # Safety
///
- /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
- /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
- /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
- /// this object must have been dropped.
+ /// The provided pointer must have been returned by a previous call to [`into_foreign`], and it
+ /// must not be passed to `from_foreign` more than once.
+ ///
+ /// [`into_foreign`]: Self::into_foreign
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self;
/// Tries to convert a foreign-owned object back to a Rust-owned one.
@@ -48,8 +55,9 @@ pub trait ForeignOwnable: Sized {
///
/// # Safety
///
- /// `ptr` must either be null or satisfy the safety requirements for
- /// [`ForeignOwnable::from_foreign`].
+ /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`].
+ ///
+ /// [`from_foreign`]: Self::from_foreign
unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
if ptr.is_null() {
None
@@ -60,17 +68,53 @@ unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
}
}
- /// Borrows a foreign-owned object.
+ /// Borrows a foreign-owned object immutably.
+ ///
+ /// This method provides a way to access a foreign-owned value from Rust immutably. It provides
+ /// you with exactly the same abilities as an `&Self` when the value is Rust-owned.
///
/// # Safety
///
- /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
- /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
+ /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
+ /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
+ /// the lifetime 'a.
+ ///
+ /// [`into_foreign`]: Self::into_foreign
+ /// [`from_foreign`]: Self::from_foreign
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
+
+ /// Borrows a foreign-owned object mutably.
+ ///
+ /// This method provides a way to access a foreign-owned value from Rust mutably. It provides
+ /// you with exactly the same abilities as an `&mut Self` when the value is Rust-owned, except
+ /// that the address of the object must not be changed.
+ ///
+ /// Note that for types like [`Arc`], an `&mut Arc<T>` only gives you immutable access to the
+ /// inner value, so this method also only provides immutable access in that case.
+ ///
+ /// In the case of `Box<T>`, this method gives you the ability to modify the inner `T`, but it
+ /// does not let you change the box itself. That is, you cannot change which allocation the box
+ /// points at.
+ ///
+ /// # Safety
+ ///
+ /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
+ /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
+ /// the lifetime 'a.
+ ///
+ /// The lifetime 'a must not overlap with the lifetime of any other call to [`borrow`] or
+ /// `borrow_mut` on the same object.
+ ///
+ /// [`into_foreign`]: Self::into_foreign
+ /// [`from_foreign`]: Self::from_foreign
+ /// [`borrow`]: Self::borrow
+ /// [`Arc`]: crate::sync::Arc
+ unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>;
}
impl ForeignOwnable for () {
type Borrowed<'a> = ();
+ type BorrowedMut<'a> = ();
fn into_foreign(self) -> *mut crate::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
@@ -79,6 +123,7 @@ fn into_foreign(self) -> *mut crate::ffi::c_void {
unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
+ unsafe fn borrow_mut<'a>(_: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a> {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (5 preceding siblings ...)
2024-11-20 11:46 ` [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
@ 2025-01-13 12:09 ` Miguel Ojeda
2025-01-13 23:52 ` Miguel Ojeda
7 siblings, 0 replies; 15+ messages in thread
From: Miguel Ojeda @ 2025-01-13 12:09 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, rust-for-linux, linux-kernel,
Martin Rodriguez Reboredo, Tamir Duberstein
On Wed, Nov 20, 2024 at 12:46 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> rust/kernel/alloc/kbox.rs | 41 ++++++++++++++++-----
Danilo: unless you don't want them, I plan to pick these (an Acked-by
would be great!). Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 2/6] rust: types: avoid `as` casts
2024-11-20 11:46 ` [PATCH v6 2/6] rust: types: avoid `as` casts Tamir Duberstein
@ 2025-01-13 13:15 ` Danilo Krummrich
0 siblings, 0 replies; 15+ messages in thread
From: Danilo Krummrich @ 2025-01-13 13:15 UTC (permalink / raw)
To: Tamir Duberstein, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel
On 20.11.2024 12:46, Tamir Duberstein wrote:
> Replace `as` casts with `cast{,_mut}` calls which are a bit safer.
>
> In one instance, remove an unnecessary `as` cast without replacement.
>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
> ---
> rust/kernel/alloc/kbox.rs | 8 ++++----
> rust/kernel/sync/arc.rs | 9 +++++----
> rust/kernel/types.rs | 2 +-
> 3 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index 9ce414361c2c6dd8eea09b11041f6c307cbc7864..3f0b04609bd487e3f50247f9f1abd5394b749c7e 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -356,13 +356,13 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
> type Borrowed<'a> = &'a T;
>
> fn into_foreign(self) -> *const crate::ffi::c_void {
> - Box::into_raw(self) as _
> + Box::into_raw(self).cast()
> }
>
> unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - unsafe { Box::from_raw(ptr as _) }
> + unsafe { Box::from_raw(ptr.cast_mut().cast()) }
> }
>
> unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
> @@ -380,13 +380,13 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
>
> fn into_foreign(self) -> *const crate::ffi::c_void {
> // SAFETY: We are still treating the box as pinned.
> - Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
> + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
> }
>
> unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
> + unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast_mut().cast())) }
> }
>
> unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index b4e492dd712137c7c39e3de3d39c0c833944828c..50645660a9c33cb121ee1b2469003b325000d840 100644
> --- a/rust/kernel/sync/arc.rs
> +++ b/rust/kernel/sync/arc.rs
> @@ -201,10 +201,11 @@ pub fn new(contents: T, flags: Flags) -> Result<Self, AllocError> {
> };
>
> let inner = KBox::new(value, flags)?;
> + let inner = KBox::leak(inner).into();
>
> // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new
> // `Arc` object.
> - Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) })
> + Ok(unsafe { Self::from_inner(inner) })
> }
> }
>
> @@ -333,13 +334,13 @@ impl<T: 'static> ForeignOwnable for Arc<T> {
> type Borrowed<'a> = ArcBorrow<'a, T>;
>
> fn into_foreign(self) -> *const crate::ffi::c_void {
> - ManuallyDrop::new(self).ptr.as_ptr() as _
> + ManuallyDrop::new(self).ptr.as_ptr().cast()
> }
>
> unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
> + let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
>
> // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
> // for the lifetime of the returned value.
> @@ -349,7 +350,7 @@ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
> unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - let inner = unsafe { NonNull::new_unchecked(ptr as *mut ArcInner<T>) };
> + let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
>
> // SAFETY: By the safety requirement of this function, we know that `ptr` came from
> // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index ec6457bb3084ae327c38ba4ba79b1601aef38244..318d2140470a90568100f86fd8c6d8084031f556 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -434,7 +434,7 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
> /// }
> ///
> /// let mut data = Empty {};
> - /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
> + /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
> /// # // SAFETY: TODO.
> /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
> /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut
2024-11-20 11:46 ` [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
@ 2025-01-13 13:15 ` Danilo Krummrich
0 siblings, 0 replies; 15+ messages in thread
From: Danilo Krummrich @ 2025-01-13 13:15 UTC (permalink / raw)
To: Tamir Duberstein, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel
On 20.11.2024 12:46, Tamir Duberstein wrote:
> It is slightly more convenient to operate on mut pointers, and this also
> properly conveys the desired ownership semantics of the trait.
>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
> ---
> rust/kernel/alloc/kbox.rs | 16 ++++++++--------
> rust/kernel/miscdevice.rs | 2 +-
> rust/kernel/sync/arc.rs | 10 +++++-----
> rust/kernel/types.rs | 14 +++++++-------
> 4 files changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index 3f0b04609bd487e3f50247f9f1abd5394b749c7e..e00c14053efbfb08d053e0f0b11247fa25d9d516 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -355,17 +355,17 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
> {
> type Borrowed<'a> = &'a T;
>
> - fn into_foreign(self) -> *const crate::ffi::c_void {
> + fn into_foreign(self) -> *mut crate::ffi::c_void {
> Box::into_raw(self).cast()
> }
>
> - unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> + unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - unsafe { Box::from_raw(ptr.cast_mut().cast()) }
> + unsafe { Box::from_raw(ptr.cast()) }
> }
>
> - unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
> + unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
> // SAFETY: The safety requirements of this method ensure that the object remains alive and
> // immutable for the duration of 'a.
> unsafe { &*ptr.cast() }
> @@ -378,18 +378,18 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
> {
> type Borrowed<'a> = Pin<&'a T>;
>
> - fn into_foreign(self) -> *const crate::ffi::c_void {
> + fn into_foreign(self) -> *mut crate::ffi::c_void {
> // SAFETY: We are still treating the box as pinned.
> Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
> }
>
> - unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> + unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast_mut().cast())) }
> + unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
> }
>
> - unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
> + unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
> // SAFETY: The safety requirements for this function ensure that the object is still alive,
> // so it is safe to dereference the raw pointer.
> // The safety requirements of `from_foreign` also ensure that the object remains alive for
> diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
> index 7e2a79b3ae263659b7e0781c05cb130d10c8accb..e58807ad28dc644fa384e9c1fb41fd6e53abea7a 100644
> --- a/rust/kernel/miscdevice.rs
> +++ b/rust/kernel/miscdevice.rs
> @@ -193,7 +193,7 @@ impl<T: MiscDevice> VtableHelper<T> {
> };
>
> // SAFETY: The open call of a file owns the private data.
> - unsafe { (*file).private_data = ptr.into_foreign().cast_mut() };
> + unsafe { (*file).private_data = ptr.into_foreign() };
>
> 0
> }
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index a11f267ce5d40b987f1f3c459271e5317ea0bae8..01d85da799d77127fc99a9b270b8a7b1ef435b6f 100644
> --- a/rust/kernel/sync/arc.rs
> +++ b/rust/kernel/sync/arc.rs
> @@ -333,24 +333,24 @@ pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> {
> impl<T: 'static> ForeignOwnable for Arc<T> {
> type Borrowed<'a> = ArcBorrow<'a, T>;
>
> - fn into_foreign(self) -> *const crate::ffi::c_void {
> + fn into_foreign(self) -> *mut crate::ffi::c_void {
> ManuallyDrop::new(self).ptr.as_ptr().cast()
> }
>
> - unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> {
> + unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
> + let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
>
> // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
> // for the lifetime of the returned value.
> unsafe { ArcBorrow::new(inner) }
> }
>
> - unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
> + unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
> // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> // call to `Self::into_foreign`.
> - let inner = unsafe { NonNull::new_unchecked(ptr.cast_mut().cast::<ArcInner<T>>()) };
> + let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
>
> // SAFETY: By the safety requirement of this function, we know that `ptr` came from
> // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index 318d2140470a90568100f86fd8c6d8084031f556..f9b398ee31fd5303f0224995f51d314a0c4ecbf2 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -29,7 +29,7 @@ pub trait ForeignOwnable: Sized {
> /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
> /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
> /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
> - fn into_foreign(self) -> *const crate::ffi::c_void;
> + fn into_foreign(self) -> *mut crate::ffi::c_void;
>
> /// Borrows a foreign-owned object.
> ///
> @@ -37,7 +37,7 @@ pub trait ForeignOwnable: Sized {
> ///
> /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> - unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>;
> + unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
>
> /// Converts a foreign-owned object back to a Rust-owned one.
> ///
> @@ -47,7 +47,7 @@ pub trait ForeignOwnable: Sized {
> /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
> /// this object must have been dropped.
> - unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self;
> + unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self;
>
> /// Tries to convert a foreign-owned object back to a Rust-owned one.
> ///
> @@ -58,7 +58,7 @@ pub trait ForeignOwnable: Sized {
> ///
> /// `ptr` must either be null or satisfy the safety requirements for
> /// [`ForeignOwnable::from_foreign`].
> - unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
> + unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
> if ptr.is_null() {
> None
> } else {
> @@ -72,13 +72,13 @@ unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
> impl ForeignOwnable for () {
> type Borrowed<'a> = ();
>
> - fn into_foreign(self) -> *const crate::ffi::c_void {
> + fn into_foreign(self) -> *mut crate::ffi::c_void {
> core::ptr::NonNull::dangling().as_ptr()
> }
>
> - unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {}
> + unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
>
> - unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {}
> + unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
> }
>
> /// Runs a cleanup function/closure when dropped.
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2024-11-20 11:46 ` [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
@ 2025-01-13 13:18 ` Danilo Krummrich
2025-01-13 15:45 ` Tamir Duberstein
2025-01-13 23:52 ` Miguel Ojeda
0 siblings, 2 replies; 15+ messages in thread
From: Danilo Krummrich @ 2025-01-13 13:18 UTC (permalink / raw)
To: Tamir Duberstein, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich
Cc: rust-for-linux, linux-kernel, Martin Rodriguez Reboredo
On 20.11.2024 12:46, Tamir Duberstein wrote:
> From: Alice Ryhl <aliceryhl@google.com>
>
> Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
> that was intended to provide mutable access to the inner value. However,
> the method accidentally made it possible to change the address of the
> object being modified, which usually isn't what we want. (And when we
> want that, it can be done by calling `from_foreign` and `into_foreign`,
> like how the old `borrow_mut` was implemented.)
>
> In this patch, we introduce an alternate definition of `borrow_mut` that
> solves the previous problem. Conceptually, given a pointer type `P` that
> implements `ForeignOwnable`, the `borrow_mut` method gives you the same
> kind of access as an `&mut P` would, except that it does not let you
> change the pointer `P` itself.
>
> This is analogous to how the existing `borrow` method provides the same
> kind of access to the inner value as an `&P`.
>
> Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
> immutable access to the inner `T`. This is because mutable references
> assume exclusive access, but there might be other handles to the same
> reference counted value, so the access isn't exclusive. The `Arc` type
> implements this by making `borrow_mut` return the same type as `borrow`.
>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> Reviewed-by: Benno Lossin <benno.lossin@proton.me>
> Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
The new functions in kbox.rs should probably use crate::ffi instead of
core::ffi arguments. Besides that,
Acked-by: Danilo Krummrich <dakr@kernel.org>
> ---
> rust/kernel/alloc/kbox.rs | 21 ++++++++++++++
> rust/kernel/sync/arc.rs | 7 +++++
> rust/kernel/types.rs | 71 ++++++++++++++++++++++++++++++++++++++---------
> 3 files changed, 86 insertions(+), 13 deletions(-)
>
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index e00c14053efbfb08d053e0f0b11247fa25d9d516..4ffc4e1b22b2b7c2ea8e8ed5b7f7a8534625249f 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -354,6 +354,7 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
> A: Allocator,
> {
> type Borrowed<'a> = &'a T;
> + type BorrowedMut<'a> = &'a mut T;
>
> fn into_foreign(self) -> *mut crate::ffi::c_void {
> Box::into_raw(self).cast()
> @@ -370,6 +371,13 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
> // immutable for the duration of 'a.
> unsafe { &*ptr.cast() }
> }
> +
> + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> &'a mut T {
> + let ptr = ptr.cast();
> + // SAFETY: The safety requirements of this method ensure that the pointer is valid and that
> + // nothing else will access the value for the duration of 'a.
> + unsafe { &mut *ptr }
> + }
> }
>
> impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
> @@ -377,6 +385,7 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
> A: Allocator,
> {
> type Borrowed<'a> = Pin<&'a T>;
> + type BorrowedMut<'a> = Pin<&'a mut T>;
>
> fn into_foreign(self) -> *mut crate::ffi::c_void {
> // SAFETY: We are still treating the box as pinned.
> @@ -399,6 +408,18 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
> // SAFETY: This pointer originates from a `Pin<Box<T>>`.
> unsafe { Pin::new_unchecked(r) }
> }
> +
> + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> Pin<&'a mut T> {
> + let ptr = ptr.cast();
> + // SAFETY: The safety requirements for this function ensure that the object is still alive,
> + // so it is safe to dereference the raw pointer.
> + // The safety requirements of `from_foreign` also ensure that the object remains alive for
> + // the lifetime of the returned value.
> + let r = unsafe { &mut *ptr };
> +
> + // SAFETY: This pointer originates from a `Pin<Box<T>>`.
> + unsafe { Pin::new_unchecked(r) }
> + }
> }
>
> impl<T, A> Deref for Box<T, A>
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index 1d26c309d21db53f1fc769562c2afb4e881c3b5b..eb5cd8b360a3507a527978aaf96dbc3a80d4ae2c 100644
> --- a/rust/kernel/sync/arc.rs
> +++ b/rust/kernel/sync/arc.rs
> @@ -332,6 +332,7 @@ pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> {
>
> impl<T: 'static> ForeignOwnable for Arc<T> {
> type Borrowed<'a> = ArcBorrow<'a, T>;
> + type BorrowedMut<'a> = Self::Borrowed<'a>;
>
> fn into_foreign(self) -> *mut crate::ffi::c_void {
> ManuallyDrop::new(self).ptr.as_ptr().cast()
> @@ -357,6 +358,12 @@ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
> // for the lifetime of the returned value.
> unsafe { ArcBorrow::new(inner) }
> }
> +
> + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> {
> + // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
> + // requirements for `borrow`.
> + unsafe { Self::borrow(ptr) }
> + }
> }
>
> impl<T: ?Sized> Deref for Arc<T> {
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index af316e291908123407f08c665c91113a666fc593..0dfaf45a755c7ce702027918e5fd3e97c407fda4 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -19,26 +19,33 @@
> /// This trait is meant to be used in cases when Rust objects are stored in C objects and
> /// eventually "freed" back to Rust.
> pub trait ForeignOwnable: Sized {
> - /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
> - /// [`ForeignOwnable::from_foreign`].
> + /// Type used to immutably borrow a value that is currently foreign-owned.
> type Borrowed<'a>;
>
> + /// Type used to mutably borrow a value that is currently foreign-owned.
> + type BorrowedMut<'a>;
> +
> /// Converts a Rust-owned object to a foreign-owned one.
> ///
> /// The foreign representation is a pointer to void. There are no guarantees for this pointer.
> /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
> - /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
> - /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
> + /// any way except for [`from_foreign`], [`try_from_foreign`], [`borrow`], or [`borrow_mut`] can
> + /// result in undefined behavior.
> + ///
> + /// [`from_foreign`]: Self::from_foreign
> + /// [`try_from_foreign`]: Self::try_from_foreign
> + /// [`borrow`]: Self::borrow
> + /// [`borrow_mut`]: Self::borrow_mut
> fn into_foreign(self) -> *mut crate::ffi::c_void;
>
> /// Converts a foreign-owned object back to a Rust-owned one.
> ///
> /// # Safety
> ///
> - /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> - /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
> - /// this object must have been dropped.
> + /// The provided pointer must have been returned by a previous call to [`into_foreign`], and it
> + /// must not be passed to `from_foreign` more than once.
> + ///
> + /// [`into_foreign`]: Self::into_foreign
> unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self;
>
> /// Tries to convert a foreign-owned object back to a Rust-owned one.
> @@ -48,8 +55,9 @@ pub trait ForeignOwnable: Sized {
> ///
> /// # Safety
> ///
> - /// `ptr` must either be null or satisfy the safety requirements for
> - /// [`ForeignOwnable::from_foreign`].
> + /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`].
> + ///
> + /// [`from_foreign`]: Self::from_foreign
> unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
> if ptr.is_null() {
> None
> @@ -60,17 +68,53 @@ unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
> }
> }
>
> - /// Borrows a foreign-owned object.
> + /// Borrows a foreign-owned object immutably.
> + ///
> + /// This method provides a way to access a foreign-owned value from Rust immutably. It provides
> + /// you with exactly the same abilities as an `&Self` when the value is Rust-owned.
> ///
> /// # Safety
> ///
> - /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> + /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
> + /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
> + /// the lifetime 'a.
> + ///
> + /// [`into_foreign`]: Self::into_foreign
> + /// [`from_foreign`]: Self::from_foreign
> unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
> +
> + /// Borrows a foreign-owned object mutably.
> + ///
> + /// This method provides a way to access a foreign-owned value from Rust mutably. It provides
> + /// you with exactly the same abilities as an `&mut Self` when the value is Rust-owned, except
> + /// that the address of the object must not be changed.
> + ///
> + /// Note that for types like [`Arc`], an `&mut Arc<T>` only gives you immutable access to the
> + /// inner value, so this method also only provides immutable access in that case.
> + ///
> + /// In the case of `Box<T>`, this method gives you the ability to modify the inner `T`, but it
> + /// does not let you change the box itself. That is, you cannot change which allocation the box
> + /// points at.
> + ///
> + /// # Safety
> + ///
> + /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
> + /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
> + /// the lifetime 'a.
> + ///
> + /// The lifetime 'a must not overlap with the lifetime of any other call to [`borrow`] or
> + /// `borrow_mut` on the same object.
> + ///
> + /// [`into_foreign`]: Self::into_foreign
> + /// [`from_foreign`]: Self::from_foreign
> + /// [`borrow`]: Self::borrow
> + /// [`Arc`]: crate::sync::Arc
> + unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>;
> }
>
> impl ForeignOwnable for () {
> type Borrowed<'a> = ();
> + type BorrowedMut<'a> = ();
>
> fn into_foreign(self) -> *mut crate::ffi::c_void {
> core::ptr::NonNull::dangling().as_ptr()
> @@ -79,6 +123,7 @@ fn into_foreign(self) -> *mut crate::ffi::c_void {
> unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
>
> unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
> + unsafe fn borrow_mut<'a>(_: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a> {}
> }
>
> /// Runs a cleanup function/closure when dropped.
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2025-01-13 13:18 ` Danilo Krummrich
@ 2025-01-13 15:45 ` Tamir Duberstein
2025-01-13 16:20 ` Miguel Ojeda
2025-01-13 23:52 ` Miguel Ojeda
1 sibling, 1 reply; 15+ messages in thread
From: Tamir Duberstein @ 2025-01-13 15:45 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, rust-for-linux, linux-kernel,
Martin Rodriguez Reboredo
On Mon, Jan 13, 2025 at 8:18 AM Danilo Krummrich <dakr@kernel.org> wrote:
>
> The new functions in kbox.rs should probably use crate::ffi instead of
> core::ffi arguments. Besides that,
Agreed. Miguel, can you do that when you apply or should I send v7?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2025-01-13 15:45 ` Tamir Duberstein
@ 2025-01-13 16:20 ` Miguel Ojeda
0 siblings, 0 replies; 15+ messages in thread
From: Miguel Ojeda @ 2025-01-13 16:20 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Danilo Krummrich, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, rust-for-linux, linux-kernel,
Martin Rodriguez Reboredo
On Mon, Jan 13, 2025 at 4:46 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> Agreed. Miguel, can you do that when you apply or should I send v7?
Of course, I will adjust them, no worries. (Thanks for the offer!)
Cheers,
Miguel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2025-01-13 13:18 ` Danilo Krummrich
2025-01-13 15:45 ` Tamir Duberstein
@ 2025-01-13 23:52 ` Miguel Ojeda
1 sibling, 0 replies; 15+ messages in thread
From: Miguel Ojeda @ 2025-01-13 23:52 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Tamir Duberstein, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, rust-for-linux, linux-kernel,
Martin Rodriguez Reboredo
On Mon, Jan 13, 2025 at 2:18 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> Acked-by: Danilo Krummrich <dakr@kernel.org>
Thanks for the quick Acks, Danilo!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (6 preceding siblings ...)
2025-01-13 12:09 ` [PATCH v6 0/6] " Miguel Ojeda
@ 2025-01-13 23:52 ` Miguel Ojeda
7 siblings, 0 replies; 15+ messages in thread
From: Miguel Ojeda @ 2025-01-13 23:52 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel,
Martin Rodriguez Reboredo
On Wed, Nov 20, 2024 at 12:46 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> This is a re-submission of Alice's patch[0]. The leading commits are
> intended to improve the consistency and ergonomics of `ForeignOwnable`,
> and to split out the code movement originally included in the patch.
>
> `ForeignOwnable::borrow_mut` is a dependency of the memory backing
> feature of `rnull`, the Rust null block driver.
>
> Link: https://lore.kernel.org/all/20230710074642.683831-1-aliceryhl@google.com/T/#u [0]
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Applied to `rust-next` -- thanks everyone!
[ Reworded title slightly. - Miguel ]
[ Reworded title slightly. - Miguel ]
[ Updated to `crate::ffi::`. Reworded title slightly. - Miguel ]
Cheers,
Miguel
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-01-13 23:53 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-20 11:45 [PATCH v6 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 2/6] rust: types: avoid `as` casts Tamir Duberstein
2025-01-13 13:15 ` Danilo Krummrich
2024-11-20 11:46 ` [PATCH v6 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
2025-01-13 13:15 ` Danilo Krummrich
2024-11-20 11:46 ` [PATCH v6 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
2024-11-20 11:46 ` [PATCH v6 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2025-01-13 13:18 ` Danilo Krummrich
2025-01-13 15:45 ` Tamir Duberstein
2025-01-13 16:20 ` Miguel Ojeda
2025-01-13 23:52 ` Miguel Ojeda
2025-01-13 12:09 ` [PATCH v6 0/6] " Miguel Ojeda
2025-01-13 23:52 ` Miguel Ojeda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).