mirror of
https://github.com/torvalds/linux.git
synced 2025-08-20 17:29:22 +02:00
rust: treewide: switch to our kernel Box
type
Now that we got the kernel `Box` type in place, convert all existing `Box` users to make use of it. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Gary Guo <gary@garyguo.net> Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20241004154149.93856-13-dakr@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
c8cfa8d0c0
commit
8373147ce4
10 changed files with 81 additions and 76 deletions
|
@ -32,7 +32,7 @@ module! {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NullBlkModule {
|
struct NullBlkModule {
|
||||||
_disk: Pin<Box<Mutex<GenDisk<NullBlkDevice>>>>,
|
_disk: Pin<KBox<Mutex<GenDisk<NullBlkDevice>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl kernel::Module for NullBlkModule {
|
impl kernel::Module for NullBlkModule {
|
||||||
|
@ -47,7 +47,7 @@ impl kernel::Module for NullBlkModule {
|
||||||
.rotational(false)
|
.rotational(false)
|
||||||
.build(format_args!("rnullb{}", 0), tagset)?;
|
.build(format_args!("rnullb{}", 0), tagset)?;
|
||||||
|
|
||||||
let disk = Box::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?;
|
let disk = KBox::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?;
|
||||||
|
|
||||||
Ok(Self { _disk: disk })
|
Ok(Self { _disk: disk })
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//! To initialize a `struct` with an in-place constructor you will need two things:
|
//! To initialize a `struct` with an in-place constructor you will need two things:
|
||||||
//! - an in-place constructor,
|
//! - an in-place constructor,
|
||||||
//! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
|
//! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
|
||||||
//! [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]).
|
//! [`UniqueArc<T>`], [`KBox<T>`] or any other smart pointer that implements [`InPlaceInit`]).
|
||||||
//!
|
//!
|
||||||
//! To get an in-place constructor there are generally three options:
|
//! To get an in-place constructor there are generally three options:
|
||||||
//! - directly creating an in-place constructor using the [`pin_init!`] macro,
|
//! - directly creating an in-place constructor using the [`pin_init!`] macro,
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
//! # a <- new_mutex!(42, "Foo::a"),
|
//! # a <- new_mutex!(42, "Foo::a"),
|
||||||
//! # b: 24,
|
//! # b: 24,
|
||||||
//! # });
|
//! # });
|
||||||
//! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL);
|
//! let foo: Result<Pin<KBox<Foo>>> = KBox::pin_init(foo, GFP_KERNEL);
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! For more information see the [`pin_init!`] macro.
|
//! For more information see the [`pin_init!`] macro.
|
||||||
|
@ -92,14 +92,14 @@
|
||||||
//! struct DriverData {
|
//! struct DriverData {
|
||||||
//! #[pin]
|
//! #[pin]
|
||||||
//! status: Mutex<i32>,
|
//! status: Mutex<i32>,
|
||||||
//! buffer: Box<[u8; 1_000_000]>,
|
//! buffer: KBox<[u8; 1_000_000]>,
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! impl DriverData {
|
//! impl DriverData {
|
||||||
//! fn new() -> impl PinInit<Self, Error> {
|
//! fn new() -> impl PinInit<Self, Error> {
|
||||||
//! try_pin_init!(Self {
|
//! try_pin_init!(Self {
|
||||||
//! status <- new_mutex!(0, "DriverData::status"),
|
//! status <- new_mutex!(0, "DriverData::status"),
|
||||||
//! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?,
|
//! buffer: KBox::init(kernel::init::zeroed(), GFP_KERNEL)?,
|
||||||
//! })
|
//! })
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
//! [`pin_init!`]: crate::pin_init!
|
//! [`pin_init!`]: crate::pin_init!
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
alloc::{box_ext::BoxExt, AllocError, Flags},
|
alloc::{box_ext::BoxExt, AllocError, Flags, KBox},
|
||||||
error::{self, Error},
|
error::{self, Error},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
sync::UniqueArc,
|
sync::UniqueArc,
|
||||||
|
@ -298,7 +298,7 @@ macro_rules! stack_pin_init {
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// #[pin]
|
/// #[pin]
|
||||||
/// a: Mutex<usize>,
|
/// a: Mutex<usize>,
|
||||||
/// b: Box<Bar>,
|
/// b: KBox<Bar>,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// struct Bar {
|
/// struct Bar {
|
||||||
|
@ -307,7 +307,7 @@ macro_rules! stack_pin_init {
|
||||||
///
|
///
|
||||||
/// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo {
|
/// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo {
|
||||||
/// a <- new_mutex!(42),
|
/// a <- new_mutex!(42),
|
||||||
/// b: Box::new(Bar {
|
/// b: KBox::new(Bar {
|
||||||
/// x: 64,
|
/// x: 64,
|
||||||
/// }, GFP_KERNEL)?,
|
/// }, GFP_KERNEL)?,
|
||||||
/// }));
|
/// }));
|
||||||
|
@ -324,7 +324,7 @@ macro_rules! stack_pin_init {
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// #[pin]
|
/// #[pin]
|
||||||
/// a: Mutex<usize>,
|
/// a: Mutex<usize>,
|
||||||
/// b: Box<Bar>,
|
/// b: KBox<Bar>,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// struct Bar {
|
/// struct Bar {
|
||||||
|
@ -333,7 +333,7 @@ macro_rules! stack_pin_init {
|
||||||
///
|
///
|
||||||
/// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo {
|
/// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo {
|
||||||
/// a <- new_mutex!(42),
|
/// a <- new_mutex!(42),
|
||||||
/// b: Box::new(Bar {
|
/// b: KBox::new(Bar {
|
||||||
/// x: 64,
|
/// x: 64,
|
||||||
/// }, GFP_KERNEL)?,
|
/// }, GFP_KERNEL)?,
|
||||||
/// }));
|
/// }));
|
||||||
|
@ -391,7 +391,7 @@ macro_rules! stack_try_pin_init {
|
||||||
/// },
|
/// },
|
||||||
/// });
|
/// });
|
||||||
/// # initializer }
|
/// # initializer }
|
||||||
/// # Box::pin_init(demo(), GFP_KERNEL).unwrap();
|
/// # KBox::pin_init(demo(), GFP_KERNEL).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Arbitrary Rust expressions can be used to set the value of a variable.
|
/// Arbitrary Rust expressions can be used to set the value of a variable.
|
||||||
|
@ -460,7 +460,7 @@ macro_rules! stack_try_pin_init {
|
||||||
/// # })
|
/// # })
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
/// let foo = Box::pin_init(Foo::new(), GFP_KERNEL);
|
/// let foo = KBox::pin_init(Foo::new(), GFP_KERNEL);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// They can also easily embed it into their own `struct`s:
|
/// They can also easily embed it into their own `struct`s:
|
||||||
|
@ -592,7 +592,7 @@ macro_rules! pin_init {
|
||||||
/// use kernel::{init::{self, PinInit}, error::Error};
|
/// use kernel::{init::{self, PinInit}, error::Error};
|
||||||
/// #[pin_data]
|
/// #[pin_data]
|
||||||
/// struct BigBuf {
|
/// struct BigBuf {
|
||||||
/// big: Box<[u8; 1024 * 1024 * 1024]>,
|
/// big: KBox<[u8; 1024 * 1024 * 1024]>,
|
||||||
/// small: [u8; 1024 * 1024],
|
/// small: [u8; 1024 * 1024],
|
||||||
/// ptr: *mut u8,
|
/// ptr: *mut u8,
|
||||||
/// }
|
/// }
|
||||||
|
@ -600,7 +600,7 @@ macro_rules! pin_init {
|
||||||
/// impl BigBuf {
|
/// impl BigBuf {
|
||||||
/// fn new() -> impl PinInit<Self, Error> {
|
/// fn new() -> impl PinInit<Self, Error> {
|
||||||
/// try_pin_init!(Self {
|
/// try_pin_init!(Self {
|
||||||
/// big: Box::init(init::zeroed(), GFP_KERNEL)?,
|
/// big: KBox::init(init::zeroed(), GFP_KERNEL)?,
|
||||||
/// small: [0; 1024 * 1024],
|
/// small: [0; 1024 * 1024],
|
||||||
/// ptr: core::ptr::null_mut(),
|
/// ptr: core::ptr::null_mut(),
|
||||||
/// }? Error)
|
/// }? Error)
|
||||||
|
@ -692,16 +692,16 @@ macro_rules! init {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use kernel::{init::{PinInit, zeroed}, error::Error};
|
/// use kernel::{alloc::KBox, init::{PinInit, zeroed}, error::Error};
|
||||||
/// struct BigBuf {
|
/// struct BigBuf {
|
||||||
/// big: Box<[u8; 1024 * 1024 * 1024]>,
|
/// big: KBox<[u8; 1024 * 1024 * 1024]>,
|
||||||
/// small: [u8; 1024 * 1024],
|
/// small: [u8; 1024 * 1024],
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl BigBuf {
|
/// impl BigBuf {
|
||||||
/// fn new() -> impl Init<Self, Error> {
|
/// fn new() -> impl Init<Self, Error> {
|
||||||
/// try_init!(Self {
|
/// try_init!(Self {
|
||||||
/// big: Box::init(zeroed(), GFP_KERNEL)?,
|
/// big: KBox::init(zeroed(), GFP_KERNEL)?,
|
||||||
/// small: [0; 1024 * 1024],
|
/// small: [0; 1024 * 1024],
|
||||||
/// }? Error)
|
/// }? Error)
|
||||||
/// }
|
/// }
|
||||||
|
@ -812,8 +812,8 @@ macro_rules! assert_pinned {
|
||||||
/// A pin-initializer for the type `T`.
|
/// A pin-initializer for the type `T`.
|
||||||
///
|
///
|
||||||
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
|
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
|
||||||
/// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
|
/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
|
||||||
/// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
|
/// the [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
|
||||||
///
|
///
|
||||||
/// Also see the [module description](self).
|
/// Also see the [module description](self).
|
||||||
///
|
///
|
||||||
|
@ -893,7 +893,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An initializer returned by [`PinInit::pin_chain`].
|
/// An initializer returned by [`PinInit::pin_chain`].
|
||||||
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
|
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
|
||||||
|
|
||||||
// SAFETY: The `__pinned_init` function is implemented such that it
|
// SAFETY: The `__pinned_init` function is implemented such that it
|
||||||
// - returns `Ok(())` on successful initialization,
|
// - returns `Ok(())` on successful initialization,
|
||||||
|
@ -919,8 +919,8 @@ where
|
||||||
/// An initializer for `T`.
|
/// An initializer for `T`.
|
||||||
///
|
///
|
||||||
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
|
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
|
||||||
/// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
|
/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
|
||||||
/// [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
|
/// the [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
|
||||||
/// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.
|
/// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.
|
||||||
///
|
///
|
||||||
/// Also see the [module description](self).
|
/// Also see the [module description](self).
|
||||||
|
@ -992,7 +992,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An initializer returned by [`Init::chain`].
|
/// An initializer returned by [`Init::chain`].
|
||||||
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
|
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
|
||||||
|
|
||||||
// SAFETY: The `__init` function is implemented such that it
|
// SAFETY: The `__init` function is implemented such that it
|
||||||
// - returns `Ok(())` on successful initialization,
|
// - returns `Ok(())` on successful initialization,
|
||||||
|
@ -1076,8 +1076,9 @@ pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use kernel::{error::Error, init::init_array_from_fn};
|
/// use kernel::{alloc::KBox, error::Error, init::init_array_from_fn};
|
||||||
/// let array: Box<[usize; 1_000]> = Box::init::<Error>(init_array_from_fn(|i| i), GFP_KERNEL).unwrap();
|
/// let array: KBox<[usize; 1_000]> =
|
||||||
|
/// KBox::init::<Error>(init_array_from_fn(|i| i), GFP_KERNEL).unwrap();
|
||||||
/// assert_eq!(array.len(), 1_000);
|
/// assert_eq!(array.len(), 1_000);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn init_array_from_fn<I, const N: usize, T, E>(
|
pub fn init_array_from_fn<I, const N: usize, T, E>(
|
||||||
|
@ -1453,7 +1454,7 @@ impl_zeroable! {
|
||||||
//
|
//
|
||||||
// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
|
// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
|
||||||
{<T: ?Sized>} Option<NonNull<T>>,
|
{<T: ?Sized>} Option<NonNull<T>>,
|
||||||
{<T: ?Sized>} Option<Box<T>>,
|
{<T: ?Sized>} Option<KBox<T>>,
|
||||||
|
|
||||||
// SAFETY: `null` pointer is valid.
|
// SAFETY: `null` pointer is valid.
|
||||||
//
|
//
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub unsafe trait InitData: Copy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AllData<T: ?Sized>(PhantomData<fn(Box<T>) -> Box<T>>);
|
pub struct AllData<T: ?Sized>(PhantomData<fn(KBox<T>) -> KBox<T>>);
|
||||||
|
|
||||||
impl<T: ?Sized> Clone for AllData<T> {
|
impl<T: ?Sized> Clone for AllData<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
//! Reference: <https://docs.kernel.org/core-api/rbtree.html>
|
//! Reference: <https://docs.kernel.org/core-api/rbtree.html>
|
||||||
|
|
||||||
use crate::{alloc::Flags, bindings, container_of, error::Result, prelude::*};
|
use crate::{alloc::Flags, bindings, container_of, error::Result, prelude::*};
|
||||||
use alloc::boxed::Box;
|
|
||||||
use core::{
|
use core::{
|
||||||
cmp::{Ord, Ordering},
|
cmp::{Ord, Ordering},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
@ -497,7 +496,7 @@ impl<K, V> Drop for RBTree<K, V> {
|
||||||
// but it is not observable. The loop invariant is still maintained.
|
// but it is not observable. The loop invariant is still maintained.
|
||||||
|
|
||||||
// SAFETY: `this` is valid per the loop invariant.
|
// SAFETY: `this` is valid per the loop invariant.
|
||||||
unsafe { drop(Box::from_raw(this.cast_mut())) };
|
unsafe { drop(KBox::from_raw(this.cast_mut())) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,7 +763,7 @@ impl<'a, K, V> Cursor<'a, K, V> {
|
||||||
// point to the links field of `Node<K, V>` objects.
|
// point to the links field of `Node<K, V>` objects.
|
||||||
let this = unsafe { container_of!(self.current.as_ptr(), Node<K, V>, links) }.cast_mut();
|
let this = unsafe { container_of!(self.current.as_ptr(), Node<K, V>, links) }.cast_mut();
|
||||||
// SAFETY: `this` is valid by the type invariants as described above.
|
// SAFETY: `this` is valid by the type invariants as described above.
|
||||||
let node = unsafe { Box::from_raw(this) };
|
let node = unsafe { KBox::from_raw(this) };
|
||||||
let node = RBTreeNode { node };
|
let node = RBTreeNode { node };
|
||||||
// SAFETY: The reference to the tree used to create the cursor outlives the cursor, so
|
// SAFETY: The reference to the tree used to create the cursor outlives the cursor, so
|
||||||
// the tree cannot change. By the tree invariant, all nodes are valid.
|
// the tree cannot change. By the tree invariant, all nodes are valid.
|
||||||
|
@ -809,7 +808,7 @@ impl<'a, K, V> Cursor<'a, K, V> {
|
||||||
// point to the links field of `Node<K, V>` objects.
|
// point to the links field of `Node<K, V>` objects.
|
||||||
let this = unsafe { container_of!(neighbor, Node<K, V>, links) }.cast_mut();
|
let this = unsafe { container_of!(neighbor, Node<K, V>, links) }.cast_mut();
|
||||||
// SAFETY: `this` is valid by the type invariants as described above.
|
// SAFETY: `this` is valid by the type invariants as described above.
|
||||||
let node = unsafe { Box::from_raw(this) };
|
let node = unsafe { KBox::from_raw(this) };
|
||||||
return Some(RBTreeNode { node });
|
return Some(RBTreeNode { node });
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -1038,7 +1037,7 @@ impl<K, V> Iterator for IterRaw<K, V> {
|
||||||
/// It contains the memory needed to hold a node that can be inserted into a red-black tree. One
|
/// It contains the memory needed to hold a node that can be inserted into a red-black tree. One
|
||||||
/// can be obtained by directly allocating it ([`RBTreeNodeReservation::new`]).
|
/// can be obtained by directly allocating it ([`RBTreeNodeReservation::new`]).
|
||||||
pub struct RBTreeNodeReservation<K, V> {
|
pub struct RBTreeNodeReservation<K, V> {
|
||||||
node: Box<MaybeUninit<Node<K, V>>>,
|
node: KBox<MaybeUninit<Node<K, V>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> RBTreeNodeReservation<K, V> {
|
impl<K, V> RBTreeNodeReservation<K, V> {
|
||||||
|
@ -1046,7 +1045,7 @@ impl<K, V> RBTreeNodeReservation<K, V> {
|
||||||
/// call to [`RBTree::insert`].
|
/// call to [`RBTree::insert`].
|
||||||
pub fn new(flags: Flags) -> Result<RBTreeNodeReservation<K, V>> {
|
pub fn new(flags: Flags) -> Result<RBTreeNodeReservation<K, V>> {
|
||||||
Ok(RBTreeNodeReservation {
|
Ok(RBTreeNodeReservation {
|
||||||
node: <Box<_> as BoxExt<_>>::new_uninit(flags)?,
|
node: KBox::new_uninit(flags)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1062,14 +1061,15 @@ impl<K, V> RBTreeNodeReservation<K, V> {
|
||||||
/// Initialises a node reservation.
|
/// Initialises a node reservation.
|
||||||
///
|
///
|
||||||
/// It then becomes an [`RBTreeNode`] that can be inserted into a tree.
|
/// It then becomes an [`RBTreeNode`] that can be inserted into a tree.
|
||||||
pub fn into_node(mut self, key: K, value: V) -> RBTreeNode<K, V> {
|
pub fn into_node(self, key: K, value: V) -> RBTreeNode<K, V> {
|
||||||
self.node.write(Node {
|
let node = KBox::write(
|
||||||
key,
|
self.node,
|
||||||
value,
|
Node {
|
||||||
links: bindings::rb_node::default(),
|
key,
|
||||||
});
|
value,
|
||||||
// SAFETY: We just wrote to it.
|
links: bindings::rb_node::default(),
|
||||||
let node = unsafe { self.node.assume_init() };
|
},
|
||||||
|
);
|
||||||
RBTreeNode { node }
|
RBTreeNode { node }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1079,7 +1079,7 @@ impl<K, V> RBTreeNodeReservation<K, V> {
|
||||||
/// The node is fully initialised (with key and value) and can be inserted into a tree without any
|
/// The node is fully initialised (with key and value) and can be inserted into a tree without any
|
||||||
/// extra allocations or failure paths.
|
/// extra allocations or failure paths.
|
||||||
pub struct RBTreeNode<K, V> {
|
pub struct RBTreeNode<K, V> {
|
||||||
node: Box<Node<K, V>>,
|
node: KBox<Node<K, V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> RBTreeNode<K, V> {
|
impl<K, V> RBTreeNode<K, V> {
|
||||||
|
@ -1091,7 +1091,9 @@ impl<K, V> RBTreeNode<K, V> {
|
||||||
|
|
||||||
/// Get the key and value from inside the node.
|
/// Get the key and value from inside the node.
|
||||||
pub fn to_key_value(self) -> (K, V) {
|
pub fn to_key_value(self) -> (K, V) {
|
||||||
(self.node.key, self.node.value)
|
let node = KBox::into_inner(self.node);
|
||||||
|
|
||||||
|
(node.key, node.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,7 +1115,7 @@ impl<K, V> RBTreeNode<K, V> {
|
||||||
/// may be freed (but only for the key/value; memory for the node itself is kept for reuse).
|
/// may be freed (but only for the key/value; memory for the node itself is kept for reuse).
|
||||||
pub fn into_reservation(self) -> RBTreeNodeReservation<K, V> {
|
pub fn into_reservation(self) -> RBTreeNodeReservation<K, V> {
|
||||||
RBTreeNodeReservation {
|
RBTreeNodeReservation {
|
||||||
node: Box::drop_contents(self.node),
|
node: KBox::drop_contents(self.node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1164,7 +1166,7 @@ impl<'a, K, V> RawVacantEntry<'a, K, V> {
|
||||||
/// The `node` must have a key such that inserting it here does not break the ordering of this
|
/// The `node` must have a key such that inserting it here does not break the ordering of this
|
||||||
/// [`RBTree`].
|
/// [`RBTree`].
|
||||||
fn insert(self, node: RBTreeNode<K, V>) -> &'a mut V {
|
fn insert(self, node: RBTreeNode<K, V>) -> &'a mut V {
|
||||||
let node = Box::into_raw(node.node);
|
let node = KBox::into_raw(node.node);
|
||||||
|
|
||||||
// SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when
|
// SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when
|
||||||
// the node is removed or replaced.
|
// the node is removed or replaced.
|
||||||
|
@ -1238,21 +1240,24 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
||||||
// SAFETY: The node was a node in the tree, but we removed it, so we can convert it
|
// SAFETY: The node was a node in the tree, but we removed it, so we can convert it
|
||||||
// back into a box.
|
// back into a box.
|
||||||
node: unsafe {
|
node: unsafe {
|
||||||
Box::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut())
|
KBox::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the value of the entry out of the map, and returns it.
|
/// Takes the value of the entry out of the map, and returns it.
|
||||||
pub fn remove(self) -> V {
|
pub fn remove(self) -> V {
|
||||||
self.remove_node().node.value
|
let rb_node = self.remove_node();
|
||||||
|
let node = KBox::into_inner(rb_node.node);
|
||||||
|
|
||||||
|
node.value
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the current node for the provided node.
|
/// Swap the current node for the provided node.
|
||||||
///
|
///
|
||||||
/// The key of both nodes must be equal.
|
/// The key of both nodes must be equal.
|
||||||
fn replace(self, node: RBTreeNode<K, V>) -> RBTreeNode<K, V> {
|
fn replace(self, node: RBTreeNode<K, V>) -> RBTreeNode<K, V> {
|
||||||
let node = Box::into_raw(node.node);
|
let node = KBox::into_raw(node.node);
|
||||||
|
|
||||||
// SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when
|
// SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when
|
||||||
// the node is removed or replaced.
|
// the node is removed or replaced.
|
||||||
|
@ -1268,7 +1273,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
||||||
// - `self.node_ptr` produces a valid pointer to a node in the tree.
|
// - `self.node_ptr` produces a valid pointer to a node in the tree.
|
||||||
// - Now that we removed this entry from the tree, we can convert the node to a box.
|
// - Now that we removed this entry from the tree, we can convert the node to a box.
|
||||||
let old_node =
|
let old_node =
|
||||||
unsafe { Box::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut()) };
|
unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut()) };
|
||||||
|
|
||||||
RBTreeNode { node: old_node }
|
RBTreeNode { node: old_node }
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,12 @@
|
||||||
//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
|
//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
alloc::{box_ext::BoxExt, AllocError, Flags},
|
alloc::{AllocError, Flags, KBox},
|
||||||
bindings,
|
bindings,
|
||||||
init::{self, InPlaceInit, Init, PinInit},
|
init::{self, InPlaceInit, Init, PinInit},
|
||||||
try_init,
|
try_init,
|
||||||
types::{ForeignOwnable, Opaque},
|
types::{ForeignOwnable, Opaque},
|
||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
|
||||||
use core::{
|
use core::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
fmt,
|
fmt,
|
||||||
|
@ -201,11 +200,11 @@ impl<T> Arc<T> {
|
||||||
data: contents,
|
data: contents,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inner = <Box<_> as BoxExt<_>>::new(value, flags)?;
|
let inner = KBox::new(value, flags)?;
|
||||||
|
|
||||||
// SAFETY: We just created `inner` with a reference count of 1, which is owned by the new
|
// SAFETY: We just created `inner` with a reference count of 1, which is owned by the new
|
||||||
// `Arc` object.
|
// `Arc` object.
|
||||||
Ok(unsafe { Self::from_inner(Box::leak(inner).into()) })
|
Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,8 +397,8 @@ impl<T: ?Sized> Drop for Arc<T> {
|
||||||
if is_zero {
|
if is_zero {
|
||||||
// The count reached zero, we must free the memory.
|
// The count reached zero, we must free the memory.
|
||||||
//
|
//
|
||||||
// SAFETY: The pointer was initialised from the result of `Box::leak`.
|
// SAFETY: The pointer was initialised from the result of `KBox::leak`.
|
||||||
unsafe { drop(Box::from_raw(self.ptr.as_ptr())) };
|
unsafe { drop(KBox::from_raw(self.ptr.as_ptr())) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,7 +640,7 @@ impl<T> UniqueArc<T> {
|
||||||
/// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet.
|
/// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet.
|
||||||
pub fn new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
|
pub fn new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
|
||||||
// INVARIANT: The refcount is initialised to a non-zero value.
|
// INVARIANT: The refcount is initialised to a non-zero value.
|
||||||
let inner = Box::try_init::<AllocError>(
|
let inner = KBox::try_init::<AllocError>(
|
||||||
try_init!(ArcInner {
|
try_init!(ArcInner {
|
||||||
// SAFETY: There are no safety requirements for this FFI call.
|
// SAFETY: There are no safety requirements for this FFI call.
|
||||||
refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
|
refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
|
||||||
|
@ -651,8 +650,8 @@ impl<T> UniqueArc<T> {
|
||||||
)?;
|
)?;
|
||||||
Ok(UniqueArc {
|
Ok(UniqueArc {
|
||||||
// INVARIANT: The newly-created object has a refcount of 1.
|
// INVARIANT: The newly-created object has a refcount of 1.
|
||||||
// SAFETY: The pointer from the `Box` is valid.
|
// SAFETY: The pointer from the `KBox` is valid.
|
||||||
inner: unsafe { Arc::from_inner(Box::leak(inner).into()) },
|
inner: unsafe { Arc::from_inner(KBox::leak(inner).into()) },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,8 @@ pub use new_condvar;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// /// Allocates a new boxed `Example`.
|
/// /// Allocates a new boxed `Example`.
|
||||||
/// fn new_example() -> Result<Pin<Box<Example>>> {
|
/// fn new_example() -> Result<Pin<KBox<Example>>> {
|
||||||
/// Box::pin_init(pin_init!(Example {
|
/// KBox::pin_init(pin_init!(Example {
|
||||||
/// value <- new_mutex!(0),
|
/// value <- new_mutex!(0),
|
||||||
/// value_changed <- new_condvar!(),
|
/// value_changed <- new_condvar!(),
|
||||||
/// }), GFP_KERNEL)
|
/// }), GFP_KERNEL)
|
||||||
|
|
|
@ -58,7 +58,7 @@ pub use new_mutex;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// // Allocate a boxed `Example`.
|
/// // Allocate a boxed `Example`.
|
||||||
/// let e = Box::pin_init(Example::new(), GFP_KERNEL)?;
|
/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?;
|
||||||
/// assert_eq!(e.c, 10);
|
/// assert_eq!(e.c, 10);
|
||||||
/// assert_eq!(e.d.lock().a, 20);
|
/// assert_eq!(e.d.lock().a, 20);
|
||||||
/// assert_eq!(e.d.lock().b, 30);
|
/// assert_eq!(e.d.lock().b, 30);
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub use new_spinlock;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// // Allocate a boxed `Example`.
|
/// // Allocate a boxed `Example`.
|
||||||
/// let e = Box::pin_init(Example::new(), GFP_KERNEL)?;
|
/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?;
|
||||||
/// assert_eq!(e.c, 10);
|
/// assert_eq!(e.c, 10);
|
||||||
/// assert_eq!(e.d.lock().a, 20);
|
/// assert_eq!(e.d.lock().a, 20);
|
||||||
/// assert_eq!(e.d.lock().b, 30);
|
/// assert_eq!(e.d.lock().b, 30);
|
||||||
|
|
|
@ -216,7 +216,7 @@ impl Queue {
|
||||||
func: Some(func),
|
func: Some(func),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.enqueue(Box::pin_init(init, flags).map_err(|_| AllocError)?);
|
self.enqueue(KBox::pin_init(init, flags).map_err(|_| AllocError)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,9 +239,9 @@ impl<T> ClosureWork<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FnOnce()> WorkItem for ClosureWork<T> {
|
impl<T: FnOnce()> WorkItem for ClosureWork<T> {
|
||||||
type Pointer = Pin<Box<Self>>;
|
type Pointer = Pin<KBox<Self>>;
|
||||||
|
|
||||||
fn run(mut this: Pin<Box<Self>>) {
|
fn run(mut this: Pin<KBox<Self>>) {
|
||||||
if let Some(func) = this.as_mut().project().take() {
|
if let Some(func) = this.as_mut().project().take() {
|
||||||
(func)()
|
(func)()
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ pub unsafe trait RawWorkItem<const ID: u64> {
|
||||||
|
|
||||||
/// Defines the method that should be called directly when a work item is executed.
|
/// Defines the method that should be called directly when a work item is executed.
|
||||||
///
|
///
|
||||||
/// This trait is implemented by `Pin<Box<T>>` and [`Arc<T>`], and is mainly intended to be
|
/// This trait is implemented by `Pin<KBox<T>>` and [`Arc<T>`], and is mainly intended to be
|
||||||
/// implemented for smart pointer types. For your own structs, you would implement [`WorkItem`]
|
/// implemented for smart pointer types. For your own structs, you would implement [`WorkItem`]
|
||||||
/// instead. The [`run`] method on this trait will usually just perform the appropriate
|
/// instead. The [`run`] method on this trait will usually just perform the appropriate
|
||||||
/// `container_of` translation and then call into the [`run`][WorkItem::run] method from the
|
/// `container_of` translation and then call into the [`run`][WorkItem::run] method from the
|
||||||
|
@ -329,7 +329,7 @@ pub unsafe trait WorkItemPointer<const ID: u64>: RawWorkItem<ID> {
|
||||||
/// This trait is used when the `work_struct` field is defined using the [`Work`] helper.
|
/// This trait is used when the `work_struct` field is defined using the [`Work`] helper.
|
||||||
pub trait WorkItem<const ID: u64 = 0> {
|
pub trait WorkItem<const ID: u64 = 0> {
|
||||||
/// The pointer type that this struct is wrapped in. This will typically be `Arc<Self>` or
|
/// The pointer type that this struct is wrapped in. This will typically be `Arc<Self>` or
|
||||||
/// `Pin<Box<Self>>`.
|
/// `Pin<KBox<Self>>`.
|
||||||
type Pointer: WorkItemPointer<ID>;
|
type Pointer: WorkItemPointer<ID>;
|
||||||
|
|
||||||
/// The method that should be called when this work item is executed.
|
/// The method that should be called when this work item is executed.
|
||||||
|
@ -567,7 +567,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: TODO.
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
|
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<KBox<T>>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
T: HasWork<T, ID>,
|
T: HasWork<T, ID>,
|
||||||
|
@ -578,7 +578,7 @@ where
|
||||||
// SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`.
|
// SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`.
|
||||||
let ptr = unsafe { T::work_container_of(ptr) };
|
let ptr = unsafe { T::work_container_of(ptr) };
|
||||||
// SAFETY: This pointer comes from `Arc::into_raw` and we've been given back ownership.
|
// SAFETY: This pointer comes from `Arc::into_raw` and we've been given back ownership.
|
||||||
let boxed = unsafe { Box::from_raw(ptr) };
|
let boxed = unsafe { KBox::from_raw(ptr) };
|
||||||
// SAFETY: The box was already pinned when it was enqueued.
|
// SAFETY: The box was already pinned when it was enqueued.
|
||||||
let pinned = unsafe { Pin::new_unchecked(boxed) };
|
let pinned = unsafe { Pin::new_unchecked(boxed) };
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: TODO.
|
// SAFETY: TODO.
|
||||||
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
|
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<KBox<T>>
|
||||||
where
|
where
|
||||||
T: WorkItem<ID, Pointer = Self>,
|
T: WorkItem<ID, Pointer = Self>,
|
||||||
T: HasWork<T, ID>,
|
T: HasWork<T, ID>,
|
||||||
|
@ -601,9 +601,9 @@ where
|
||||||
// SAFETY: We're not going to move `self` or any of its fields, so its okay to temporarily
|
// SAFETY: We're not going to move `self` or any of its fields, so its okay to temporarily
|
||||||
// remove the `Pin` wrapper.
|
// remove the `Pin` wrapper.
|
||||||
let boxed = unsafe { Pin::into_inner_unchecked(self) };
|
let boxed = unsafe { Pin::into_inner_unchecked(self) };
|
||||||
let ptr = Box::into_raw(boxed);
|
let ptr = KBox::into_raw(boxed);
|
||||||
|
|
||||||
// SAFETY: Pointers into a `Box` point at a valid value.
|
// SAFETY: Pointers into a `KBox` point at a valid value.
|
||||||
let work_ptr = unsafe { T::raw_get_work(ptr) };
|
let work_ptr = unsafe { T::raw_get_work(ptr) };
|
||||||
// SAFETY: `raw_get_work` returns a pointer to a valid value.
|
// SAFETY: `raw_get_work` returns a pointer to a valid value.
|
||||||
let work_ptr = unsafe { Work::raw_get(work_ptr) };
|
let work_ptr = unsafe { Work::raw_get(work_ptr) };
|
||||||
|
|
|
@ -243,7 +243,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
|
||||||
/// struct DriverData {
|
/// struct DriverData {
|
||||||
/// #[pin]
|
/// #[pin]
|
||||||
/// queue: Mutex<Vec<Command>>,
|
/// queue: Mutex<Vec<Command>>,
|
||||||
/// buf: Box<[u8; 1024 * 1024]>,
|
/// buf: KBox<[u8; 1024 * 1024]>,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -252,7 +252,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
|
||||||
/// struct DriverData {
|
/// struct DriverData {
|
||||||
/// #[pin]
|
/// #[pin]
|
||||||
/// queue: Mutex<Vec<Command>>,
|
/// queue: Mutex<Vec<Command>>,
|
||||||
/// buf: Box<[u8; 1024 * 1024]>,
|
/// buf: KBox<[u8; 1024 * 1024]>,
|
||||||
/// raw_info: *mut Info,
|
/// raw_info: *mut Info,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
@ -282,7 +282,7 @@ pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
/// struct DriverData {
|
/// struct DriverData {
|
||||||
/// #[pin]
|
/// #[pin]
|
||||||
/// queue: Mutex<Vec<Command>>,
|
/// queue: Mutex<Vec<Command>>,
|
||||||
/// buf: Box<[u8; 1024 * 1024]>,
|
/// buf: KBox<[u8; 1024 * 1024]>,
|
||||||
/// raw_info: *mut Info,
|
/// raw_info: *mut Info,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue