* [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut`
@ 2024-11-04 21:20 Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
` (5 more replies)
0 siblings, 6 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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 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/sync/arc.rs | 42 ++++++++++++++-------
rust/kernel/types.rs | 93 +++++++++++++++++++++++++++++++++++------------
3 files changed, 129 insertions(+), 47 deletions(-)
---
base-commit: ae7851c29747fa3765ecb722fe722117a346f988
change-id: 20241030-borrow-mut-75f181feef4c
Best regards,
--
Tamir Duberstein <tamird@gmail.com>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 1/6] rust: arc: use `NonNull::new_unchecked`
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 2/6] rust: types: avoid `as` casts Tamir Duberstein
` (4 subsequent siblings)
5 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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`.
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.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 db9da352d588f65348aa7a5204abbb165b70197f..2c9b7d4a2554278ce8608f4f4c7f9cfe87b21492 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -337,9 +337,9 @@ fn into_foreign(self) -> *const core::ffi::c_void {
}
unsafe fn borrow<'a>(ptr: *const core::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 core::ffi::c_void) -> ArcBorrow<'a, T> {
}
unsafe fn from_foreign(ptr: *const core::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] 23+ messages in thread
* [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
2024-11-08 11:35 ` Alice Ryhl
2024-11-08 13:13 ` Miguel Ojeda
2024-11-04 21:20 ` [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
` (3 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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{,_const,_mut}` which are a bit safer.
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
rust/kernel/alloc/kbox.rs | 10 ++++++----
rust/kernel/sync/arc.rs | 9 +++++----
rust/kernel/types.rs | 2 +-
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index d69c32496b86a2315f81cafc8e6771ebb0cf10d1..b6b6723098b6b30743bf38c97aab0e701a5a1be4 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 core::ffi::c_void {
- Box::into_raw(self) as _
+ Box::into_raw(self).cast_const().cast()
}
unsafe fn from_foreign(ptr: *const core::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 core::ffi::c_void) -> &'a T {
@@ -380,13 +380,15 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
fn into_foreign(self) -> *const core::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_const()
+ .cast()
}
unsafe fn from_foreign(ptr: *const core::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 core::ffi::c_void) -> Pin<&'a T> {
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 2c9b7d4a2554278ce8608f4f4c7f9cfe87b21492..af383bcd003e1122ebe1b62a49fe40279458e379 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 core::ffi::c_void {
- ManuallyDrop::new(self).ptr.as_ptr() as _
+ ManuallyDrop::new(self).ptr.as_ptr().cast_const().cast()
}
unsafe fn borrow<'a>(ptr: *const core::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 core::ffi::c_void) -> ArcBorrow<'a, T> {
unsafe fn from_foreign(ptr: *const core::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 fae80814fa1c5e0f11933f2f15e173f0e3a10fe0..364dd2dc438eb7d1c4d0a4525bf2305a42297b2b 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -418,7 +418,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] 23+ messages in thread
* [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 2/6] rust: types: avoid `as` casts Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
2024-11-08 11:38 ` Alice Ryhl
2024-11-04 21:20 ` [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
` (2 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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.
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 af383bcd003e1122ebe1b62a49fe40279458e379..9adea755a5ad1a7b03f7fc30a7abc76c1f966c6c 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] 23+ messages in thread
* [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (2 preceding siblings ...)
2024-11-04 21:20 ` [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
2024-11-08 11:39 ` Alice Ryhl
2024-11-04 21:20 ` [PATCH v2 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
5 siblings, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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.
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
---
rust/kernel/alloc/kbox.rs | 22 ++++++++++------------
rust/kernel/sync/arc.rs | 12 ++++++------
rust/kernel/types.rs | 14 +++++++-------
3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index b6b6723098b6b30743bf38c97aab0e701a5a1be4..99d0fc0148bb8779e5a769a6e74291ef8101bf77 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 core::ffi::c_void {
- Box::into_raw(self).cast_const().cast()
+ fn into_foreign(self) -> *mut core::ffi::c_void {
+ Box::into_raw(self).cast()
}
- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut core::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 core::ffi::c_void) -> &'a T {
+ unsafe fn borrow<'a>(ptr: *mut core::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,20 +378,18 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
{
type Borrowed<'a> = Pin<&'a T>;
- fn into_foreign(self) -> *const core::ffi::c_void {
+ fn into_foreign(self) -> *mut core::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
- Box::into_raw(unsafe { Pin::into_inner_unchecked(self) })
- .cast_const()
- .cast()
+ Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
}
- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut core::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 core::ffi::c_void) -> Pin<&'a T> {
+ unsafe fn borrow<'a>(ptr: *mut core::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/sync/arc.rs b/rust/kernel/sync/arc.rs
index 9adea755a5ad1a7b03f7fc30a7abc76c1f966c6c..10819dc28b64038b9abc55b01c069826d1e5befa 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 core::ffi::c_void {
- ManuallyDrop::new(self).ptr.as_ptr().cast_const().cast()
+ fn into_foreign(self) -> *mut core::ffi::c_void {
+ ManuallyDrop::new(self).ptr.as_ptr().cast()
}
- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> {
+ unsafe fn borrow<'a>(ptr: *mut core::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 core::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut core::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 364dd2dc438eb7d1c4d0a4525bf2305a42297b2b..59e71bd158713bb8e12cac95e134f57a277c1b49 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 core::ffi::c_void;
+ fn into_foreign(self) -> *mut core::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 core::ffi::c_void) -> Self::Borrowed<'a>;
+ unsafe fn borrow<'a>(ptr: *mut core::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 core::ffi::c_void) -> Self;
+ unsafe fn from_foreign(ptr: *mut core::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 core::ffi::c_void) -> Option<Self> {
+ unsafe fn try_from_foreign(ptr: *mut core::ffi::c_void) -> Option<Self> {
if ptr.is_null() {
None
} else {
@@ -72,13 +72,13 @@ unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option<Self> {
impl ForeignOwnable for () {
type Borrowed<'a> = ();
- fn into_foreign(self) -> *const core::ffi::c_void {
+ fn into_foreign(self) -> *mut core::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
}
- unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {}
+ unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> {}
- unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {}
+ unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 5/6] rust: reorder `ForeignOwnable` items
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (3 preceding siblings ...)
2024-11-04 21:20 ` [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
2024-11-08 11:42 ` Alice Ryhl
2024-11-04 21:20 ` [PATCH v2 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
5 siblings, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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.
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 10819dc28b64038b9abc55b01c069826d1e5befa..3c779b343aa8c396d2d4b7efdbc0f1ef524a0f1c 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -337,25 +337,25 @@ fn into_foreign(self) -> *mut core::ffi::c_void {
ManuallyDrop::new(self).ptr.as_ptr().cast()
}
- unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> {
+ unsafe fn from_foreign(ptr: *mut core::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 core::ffi::c_void) -> Self {
+ unsafe fn borrow<'a>(ptr: *mut core::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 59e71bd158713bb8e12cac95e134f57a277c1b49..b8f3594737401a3df841f30a20c4bd85743853ef 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 core::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 core::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 core::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 core::ffi::c_void) -> Self::Borrowed<'a>;
}
impl ForeignOwnable for () {
@@ -76,9 +76,9 @@ fn into_foreign(self) -> *mut core::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
}
- unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> {}
-
unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {}
+
+ unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 6/6] rust: add improved version of `ForeignOwnable::borrow_mut`
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
` (4 preceding siblings ...)
2024-11-04 21:20 ` [PATCH v2 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
@ 2024-11-04 21:20 ` Tamir Duberstein
5 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-04 21:20 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>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@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 99d0fc0148bb8779e5a769a6e74291ef8101bf77..c7edcd970fe6abe2afce5364a5f6c565452da85e 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 core::ffi::c_void {
Box::into_raw(self).cast()
@@ -370,6 +371,13 @@ unsafe fn borrow<'a>(ptr: *mut core::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 core::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
@@ -399,6 +408,18 @@ unsafe fn borrow<'a>(ptr: *mut core::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 3c779b343aa8c396d2d4b7efdbc0f1ef524a0f1c..8a0f44da8f732afca6009a078e90bd7a14034240 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 core::ffi::c_void {
ManuallyDrop::new(self).ptr.as_ptr().cast()
@@ -357,6 +358,12 @@ unsafe fn borrow<'a>(ptr: *mut core::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 b8f3594737401a3df841f30a20c4bd85743853ef..c74223579111fe36c7c7cd135ba95f25f0b33fab 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 core::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 core::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 core::ffi::c_void) -> Option<Self> {
if ptr.is_null() {
None
@@ -60,17 +68,53 @@ unsafe fn try_from_foreign(ptr: *mut core::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 core::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 core::ffi::c_void) -> Self::BorrowedMut<'a>;
}
impl ForeignOwnable for () {
type Borrowed<'a> = ();
+ type BorrowedMut<'a> = ();
fn into_foreign(self) -> *mut core::ffi::c_void {
core::ptr::NonNull::dangling().as_ptr()
@@ -79,6 +123,7 @@ fn into_foreign(self) -> *mut core::ffi::c_void {
unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {}
unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> {}
+ unsafe fn borrow_mut<'a>(_: *mut core::ffi::c_void) -> Self::BorrowedMut<'a> {}
}
/// Runs a cleanup function/closure when dropped.
--
2.47.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-04 21:20 ` [PATCH v2 2/6] rust: types: avoid `as` casts Tamir Duberstein
@ 2024-11-08 11:35 ` Alice Ryhl
2024-11-08 12:22 ` Tamir Duberstein
2024-11-08 13:14 ` Miguel Ojeda
2024-11-08 13:13 ` Miguel Ojeda
1 sibling, 2 replies; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 11:35 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> Replace `as` casts with `cast{,_const,_mut}` which are a bit safer.
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
The compiler auto-converts from *mut to *const, so only cast_mut() is
necessary. I think this will still compile if you get rid of all of
the cast_const() calls.
Alice
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-04 21:20 ` [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
@ 2024-11-08 11:38 ` Alice Ryhl
2024-11-08 12:29 ` Tamir Duberstein
0 siblings, 1 reply; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 11:38 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> The new SAFETY comment style is taken from existing comments in `deref`
> and `drop.
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index af383bcd003e1122ebe1b62a49fe40279458e379..9adea755a5ad1a7b03f7fc30a7abc76c1f966c6c 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();
I would normally prefer to avoid creating a reference to the entire
ArcInner, but in this particular case it is okay due to the specifics
of how Arc works.
Alice
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut
2024-11-04 21:20 ` [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
@ 2024-11-08 11:39 ` Alice Ryhl
2024-11-08 12:23 ` Tamir Duberstein
0 siblings, 1 reply; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 11:39 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> It is slightly more convenient to operate on mut pointers, and this also
> properly conveys the desired ownership semantics of the trait.
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Normally you would put your SoB after RB tags.
Alice
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 5/6] rust: reorder `ForeignOwnable` items
2024-11-04 21:20 ` [PATCH v2 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
@ 2024-11-08 11:42 ` Alice Ryhl
0 siblings, 0 replies; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 11:42 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> `{into,from}_foreign` before `borrow` is slightly more logical.
>
> This removes an inconsistency with `kbox.rs` which already uses this
> ordering.
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
I don't think this is super important, but shrug.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-08 11:35 ` Alice Ryhl
@ 2024-11-08 12:22 ` Tamir Duberstein
2024-11-08 13:15 ` Miguel Ojeda
2024-11-08 13:14 ` Miguel Ojeda
1 sibling, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 12:22 UTC (permalink / raw)
To: Alice Ryhl
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 6:35 AM Alice Ryhl <aliceryhl@google.com> wrote:
>
> On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
> >
> > Replace `as` casts with `cast{,_const,_mut}` which are a bit safer.
> >
> > Signed-off-by: Tamir Duberstein <tamird@gmail.com>
>
> The compiler auto-converts from *mut to *const, so only cast_mut() is
> necessary. I think this will still compile if you get rid of all of
> the cast_const() calls.
I thought that wouldn't work because of type inference but it does - I
guess the compiler derefs *mut T to *const T before the cast() to
*const U.
Will change in v3, thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut
2024-11-08 11:39 ` Alice Ryhl
@ 2024-11-08 12:23 ` Tamir Duberstein
0 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 12:23 UTC (permalink / raw)
To: Alice Ryhl
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 6:39 AM Alice Ryhl <aliceryhl@google.com> wrote:
>
> On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
> >
> > It is slightly more convenient to operate on mut pointers, and this also
> > properly conveys the desired ownership semantics of the trait.
> >
> > Signed-off-by: Tamir Duberstein <tamird@gmail.com>
> > Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
> > Reviewed-by: Alice Ryhl <aliceryhl@google.com>
>
> Normally you would put your SoB after RB tags.
>
> Alice
Thanks, will do in v3.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-08 11:38 ` Alice Ryhl
@ 2024-11-08 12:29 ` Tamir Duberstein
2024-11-08 12:37 ` Alice Ryhl
0 siblings, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 12:29 UTC (permalink / raw)
To: Alice Ryhl
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 6:38 AM Alice Ryhl <aliceryhl@google.com> wrote:
> > diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> > index af383bcd003e1122ebe1b62a49fe40279458e379..9adea755a5ad1a7b03f7fc30a7abc76c1f966c6c 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();
>
> I would normally prefer to avoid creating a reference to the entire
> ArcInner, but in this particular case it is okay due to the specifics
> of how Arc works.
Note that this particular line appears also in the Drop impl just
below. That said, can you help me understand the concern with creating
a reference to the entire ArcInner?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-08 12:29 ` Tamir Duberstein
@ 2024-11-08 12:37 ` Alice Ryhl
2024-11-08 12:40 ` Tamir Duberstein
0 siblings, 1 reply; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 12:37 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 1:30 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> On Fri, Nov 8, 2024 at 6:38 AM Alice Ryhl <aliceryhl@google.com> wrote:
> > > diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> > > index af383bcd003e1122ebe1b62a49fe40279458e379..9adea755a5ad1a7b03f7fc30a7abc76c1f966c6c 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();
> >
> > I would normally prefer to avoid creating a reference to the entire
> > ArcInner, but in this particular case it is okay due to the specifics
> > of how Arc works.
>
> Note that this particular line appears also in the Drop impl just
> below. That said, can you help me understand the concern with creating
> a reference to the entire ArcInner?
Creating a shared reference to the entire ArcInner is an assertion
that no &mut exists to any part of the ArcInner, even though you only
access the refcount field. In this particular case, asserting shared
access to the `data` field is not a problem due to how Arc works, so
it's okay, but the pattern is problematic in other cases.
You could write `unsafe { (*self.ptr.as_ptr()).refcount.get() }` to
avoid the as_ref call.
Alice
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-08 12:37 ` Alice Ryhl
@ 2024-11-08 12:40 ` Tamir Duberstein
2024-11-08 12:47 ` Alice Ryhl
0 siblings, 1 reply; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 12:40 UTC (permalink / raw)
To: Alice Ryhl
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 7:37 AM Alice Ryhl <aliceryhl@google.com> wrote:
> You could write `unsafe { (*self.ptr.as_ptr()).refcount.get() }` to
> avoid the as_ref call.
Doesn't `(*self.ptr.as_ptr())` have the same problem?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-08 12:40 ` Tamir Duberstein
@ 2024-11-08 12:47 ` Alice Ryhl
2024-11-08 12:53 ` Tamir Duberstein
0 siblings, 1 reply; 23+ messages in thread
From: Alice Ryhl @ 2024-11-08 12:47 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 1:41 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> On Fri, Nov 8, 2024 at 7:37 AM Alice Ryhl <aliceryhl@google.com> wrote:
> > You could write `unsafe { (*self.ptr.as_ptr()).refcount.get() }` to
> > avoid the as_ref call.
>
> Doesn't `(*self.ptr.as_ptr())` have the same problem?
It's not quite the same. Both `*ptr` and `(*ptr).field` are place
expressions which do not inherently involve the creation of a
reference in the way that `NonNull::as_ref` does.
Alice
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment
2024-11-08 12:47 ` Alice Ryhl
@ 2024-11-08 12:53 ` Tamir Duberstein
0 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 12:53 UTC (permalink / raw)
To: Alice Ryhl
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 7:47 AM Alice Ryhl <aliceryhl@google.com> wrote:
>
> On Fri, Nov 8, 2024 at 1:41 PM Tamir Duberstein <tamird@gmail.com> wrote:
> >
> > On Fri, Nov 8, 2024 at 7:37 AM Alice Ryhl <aliceryhl@google.com> wrote:
> > > You could write `unsafe { (*self.ptr.as_ptr()).refcount.get() }` to
> > > avoid the as_ref call.
> >
> > Doesn't `(*self.ptr.as_ptr())` have the same problem?
>
> It's not quite the same. Both `*ptr` and `(*ptr).field` are place
> expressions which do not inherently involve the creation of a
> reference in the way that `NonNull::as_ref` does.
Thanks for explaining!
Tamir
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-04 21:20 ` [PATCH v2 2/6] rust: types: avoid `as` casts Tamir Duberstein
2024-11-08 11:35 ` Alice Ryhl
@ 2024-11-08 13:13 ` Miguel Ojeda
2024-11-08 13:14 ` Tamir Duberstein
1 sibling, 1 reply; 23+ messages in thread
From: Miguel Ojeda @ 2024-11-08 13:13 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
On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> - /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
> + /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
Nit: this one does not change it to `cast_*()`.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-08 13:13 ` Miguel Ojeda
@ 2024-11-08 13:14 ` Tamir Duberstein
0 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 13:14 UTC (permalink / raw)
To: Miguel Ojeda
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
On Fri, Nov 8, 2024 at 8:13 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Mon, Nov 4, 2024 at 10:20 PM Tamir Duberstein <tamird@gmail.com> wrote:
> >
> > - /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
> > + /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
>
> Nit: this one does not change it to `cast_*()`.
Ack, will mention this in the commit message.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-08 11:35 ` Alice Ryhl
2024-11-08 12:22 ` Tamir Duberstein
@ 2024-11-08 13:14 ` Miguel Ojeda
1 sibling, 0 replies; 23+ messages in thread
From: Miguel Ojeda @ 2024-11-08 13:14 UTC (permalink / raw)
To: Alice Ryhl
Cc: Tamir Duberstein, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 12:35 PM Alice Ryhl <aliceryhl@google.com> wrote:
>
> The compiler auto-converts from *mut to *const, so only cast_mut() is
> necessary. I think this will still compile if you get rid of all of
> the cast_const() calls.
Yeah, if there was a mode/lint that forced us to avoid the coercion,
then I guess this could eventually make sense as a more explicit (and
symmetric) style around raw pointers -- I opened:
https://github.com/rust-lang/rust-clippy/issues/13667
to see what others think.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-08 12:22 ` Tamir Duberstein
@ 2024-11-08 13:15 ` Miguel Ojeda
2024-11-08 13:20 ` Tamir Duberstein
0 siblings, 1 reply; 23+ messages in thread
From: Miguel Ojeda @ 2024-11-08 13:15 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Alice Ryhl, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 1:22 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> guess the compiler derefs *mut T to *const T before the cast() to
I guess you mean "coerces"? i.e. there shouldn't be a deref, no?
Cheers,
Miguel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] rust: types: avoid `as` casts
2024-11-08 13:15 ` Miguel Ojeda
@ 2024-11-08 13:20 ` Tamir Duberstein
0 siblings, 0 replies; 23+ messages in thread
From: Tamir Duberstein @ 2024-11-08 13:20 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Alice Ryhl, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel
On Fri, Nov 8, 2024 at 8:15 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Fri, Nov 8, 2024 at 1:22 PM Tamir Duberstein <tamird@gmail.com> wrote:
> >
> > guess the compiler derefs *mut T to *const T before the cast() to
>
> I guess you mean "coerces"? i.e. there shouldn't be a deref, no?
I was using "deref" in "deref coercion" sense:
https://doc.rust-lang.org/std/ops/trait.Deref.html#deref-coercion
But it seems that what's really going on is indeed automatic coercion
before the cast() call.
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2024-11-08 13:20 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-04 21:20 [PATCH v2 0/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 1/6] rust: arc: use `NonNull::new_unchecked` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 2/6] rust: types: avoid `as` casts Tamir Duberstein
2024-11-08 11:35 ` Alice Ryhl
2024-11-08 12:22 ` Tamir Duberstein
2024-11-08 13:15 ` Miguel Ojeda
2024-11-08 13:20 ` Tamir Duberstein
2024-11-08 13:14 ` Miguel Ojeda
2024-11-08 13:13 ` Miguel Ojeda
2024-11-08 13:14 ` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 3/6] rust: arc: split unsafe block, add missing comment Tamir Duberstein
2024-11-08 11:38 ` Alice Ryhl
2024-11-08 12:29 ` Tamir Duberstein
2024-11-08 12:37 ` Alice Ryhl
2024-11-08 12:40 ` Tamir Duberstein
2024-11-08 12:47 ` Alice Ryhl
2024-11-08 12:53 ` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 4/6] rust: change `ForeignOwnable` pointer to mut Tamir Duberstein
2024-11-08 11:39 ` Alice Ryhl
2024-11-08 12:23 ` Tamir Duberstein
2024-11-04 21:20 ` [PATCH v2 5/6] rust: reorder `ForeignOwnable` items Tamir Duberstein
2024-11-08 11:42 ` Alice Ryhl
2024-11-04 21:20 ` [PATCH v2 6/6] rust: add improved version of `ForeignOwnable::borrow_mut` Tamir Duberstein
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).