Commit c34aa00d authored by Wedson Almeida Filho's avatar Wedson Almeida Filho Committed by Miguel Ojeda

rust: init: update `init` module to take allocation flags

This is the last component in the conversion for allocators to take
allocation flags as parameters.
Reviewed-by: default avatarBenno Lossin <benno.lossin@proton.me>
Signed-off-by: default avatarWedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-10-wedsonaf@gmail.comSigned-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent cc41670e
...@@ -68,7 +68,7 @@ ...@@ -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); //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL);
//! ``` //! ```
//! //!
//! For more information see the [`pin_init!`] macro. //! For more information see the [`pin_init!`] macro.
...@@ -80,7 +80,8 @@ ...@@ -80,7 +80,8 @@
//! //!
//! ```rust //! ```rust
//! # use kernel::sync::{new_mutex, Arc, Mutex}; //! # use kernel::sync::{new_mutex, Arc, Mutex};
//! let mtx: Result<Arc<Mutex<usize>>> = Arc::pin_init(new_mutex!(42, "example::mtx")); //! let mtx: Result<Arc<Mutex<usize>>> =
//! Arc::pin_init(new_mutex!(42, "example::mtx"), GFP_KERNEL);
//! ``` //! ```
//! //!
//! To declare an init macro/function you just return an [`impl PinInit<T, E>`]: //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]:
...@@ -99,7 +100,7 @@ ...@@ -99,7 +100,7 @@
//! 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())?, //! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?,
//! }) //! })
//! } //! }
//! } //! }
...@@ -210,7 +211,7 @@ ...@@ -210,7 +211,7 @@
//! [`pin_init!`]: crate::pin_init! //! [`pin_init!`]: crate::pin_init!
use crate::{ use crate::{
alloc::{box_ext::BoxExt, flags::*}, alloc::{box_ext::BoxExt, Flags},
error::{self, Error}, error::{self, Error},
sync::UniqueArc, sync::UniqueArc,
types::{Opaque, ScopeGuard}, types::{Opaque, ScopeGuard},
...@@ -391,7 +392,7 @@ macro_rules! stack_try_pin_init { ...@@ -391,7 +392,7 @@ macro_rules! stack_try_pin_init {
/// }, /// },
/// }); /// });
/// # initializer } /// # initializer }
/// # Box::pin_init(demo()).unwrap(); /// # Box::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.
...@@ -461,7 +462,7 @@ macro_rules! stack_try_pin_init { ...@@ -461,7 +462,7 @@ macro_rules! stack_try_pin_init {
/// # }) /// # })
/// # } /// # }
/// # } /// # }
/// let foo = Box::pin_init(Foo::new()); /// let foo = Box::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:
...@@ -601,7 +602,7 @@ macro_rules! pin_init { ...@@ -601,7 +602,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())?, /// big: Box::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)
...@@ -702,7 +703,7 @@ macro_rules! init { ...@@ -702,7 +703,7 @@ macro_rules! init {
/// 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())?, /// big: Box::init(zeroed(), GFP_KERNEL)?,
/// small: [0; 1024 * 1024], /// small: [0; 1024 * 1024],
/// }? Error) /// }? Error)
/// } /// }
...@@ -1014,7 +1015,7 @@ pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> { ...@@ -1014,7 +1015,7 @@ pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {
/// ///
/// ```rust /// ```rust
/// use kernel::{error::Error, init::init_array_from_fn}; /// use kernel::{error::Error, init::init_array_from_fn};
/// let array: Box<[usize; 1_000]> = Box::init::<Error>(init_array_from_fn(|i| i)).unwrap(); /// let array: Box<[usize; 1_000]> = Box::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>(
...@@ -1058,7 +1059,7 @@ pub fn init_array_from_fn<I, const N: usize, T, E>( ...@@ -1058,7 +1059,7 @@ pub fn init_array_from_fn<I, const N: usize, T, E>(
/// ```rust /// ```rust
/// use kernel::{sync::{Arc, Mutex}, init::pin_init_array_from_fn, new_mutex}; /// use kernel::{sync::{Arc, Mutex}, init::pin_init_array_from_fn, new_mutex};
/// let array: Arc<[Mutex<usize>; 1_000]> = /// let array: Arc<[Mutex<usize>; 1_000]> =
/// Arc::pin_init(pin_init_array_from_fn(|i| new_mutex!(i))).unwrap(); /// Arc::pin_init(pin_init_array_from_fn(|i| new_mutex!(i)), GFP_KERNEL).unwrap();
/// assert_eq!(array.len(), 1_000); /// assert_eq!(array.len(), 1_000);
/// ``` /// ```
pub fn pin_init_array_from_fn<I, const N: usize, T, E>( pub fn pin_init_array_from_fn<I, const N: usize, T, E>(
...@@ -1116,7 +1117,7 @@ pub trait InPlaceInit<T>: Sized { ...@@ -1116,7 +1117,7 @@ pub trait InPlaceInit<T>: Sized {
/// type. /// type.
/// ///
/// If `T: !Unpin` it will not be able to move afterwards. /// If `T: !Unpin` it will not be able to move afterwards.
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E>
where where
E: From<AllocError>; E: From<AllocError>;
...@@ -1124,7 +1125,7 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> ...@@ -1124,7 +1125,7 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
/// type. /// type.
/// ///
/// If `T: !Unpin` it will not be able to move afterwards. /// If `T: !Unpin` it will not be able to move afterwards.
fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>> fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Pin<Self>>
where where
Error: From<E>, Error: From<E>,
{ {
...@@ -1132,16 +1133,16 @@ fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>> ...@@ -1132,16 +1133,16 @@ fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>>
let init = unsafe { let init = unsafe {
pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
}; };
Self::try_pin_init(init) Self::try_pin_init(init, flags)
} }
/// Use the given initializer to in-place initialize a `T`. /// Use the given initializer to in-place initialize a `T`.
fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
where where
E: From<AllocError>; E: From<AllocError>;
/// Use the given initializer to in-place initialize a `T`. /// Use the given initializer to in-place initialize a `T`.
fn init<E>(init: impl Init<T, E>) -> error::Result<Self> fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
where where
Error: From<E>, Error: From<E>,
{ {
...@@ -1149,17 +1150,17 @@ fn init<E>(init: impl Init<T, E>) -> error::Result<Self> ...@@ -1149,17 +1150,17 @@ fn init<E>(init: impl Init<T, E>) -> error::Result<Self>
let init = unsafe { let init = unsafe {
init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
}; };
Self::try_init(init) Self::try_init(init, flags)
} }
} }
impl<T> InPlaceInit<T> for Box<T> { impl<T> InPlaceInit<T> for Box<T> {
#[inline] #[inline]
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E>
where where
E: From<AllocError>, E: From<AllocError>,
{ {
let mut this = <Box<_> as BoxExt<_>>::new_uninit(GFP_KERNEL)?; let mut this = <Box<_> as BoxExt<_>>::new_uninit(flags)?;
let slot = this.as_mut_ptr(); let slot = this.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped, // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid and will not be moved, because we pin it later. // slot is valid and will not be moved, because we pin it later.
...@@ -1169,11 +1170,11 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> ...@@ -1169,11 +1170,11 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
} }
#[inline] #[inline]
fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
where where
E: From<AllocError>, E: From<AllocError>,
{ {
let mut this = <Box<_> as BoxExt<_>>::new_uninit(GFP_KERNEL)?; let mut this = <Box<_> as BoxExt<_>>::new_uninit(flags)?;
let slot = this.as_mut_ptr(); let slot = this.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped, // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid. // slot is valid.
...@@ -1185,11 +1186,11 @@ fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> ...@@ -1185,11 +1186,11 @@ fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
impl<T> InPlaceInit<T> for UniqueArc<T> { impl<T> InPlaceInit<T> for UniqueArc<T> {
#[inline] #[inline]
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E>
where where
E: From<AllocError>, E: From<AllocError>,
{ {
let mut this = UniqueArc::new_uninit(GFP_KERNEL)?; let mut this = UniqueArc::new_uninit(flags)?;
let slot = this.as_mut_ptr(); let slot = this.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped, // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid and will not be moved, because we pin it later. // slot is valid and will not be moved, because we pin it later.
...@@ -1199,11 +1200,11 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> ...@@ -1199,11 +1200,11 @@ fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
} }
#[inline] #[inline]
fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
where where
E: From<AllocError>, E: From<AllocError>,
{ {
let mut this = UniqueArc::new_uninit(GFP_KERNEL)?; let mut this = UniqueArc::new_uninit(flags)?;
let slot = this.as_mut_ptr(); let slot = this.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped, // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid. // slot is valid.
......
...@@ -182,22 +182,22 @@ pub fn new(contents: T, flags: Flags) -> Result<Self, AllocError> { ...@@ -182,22 +182,22 @@ pub fn new(contents: T, flags: Flags) -> Result<Self, AllocError> {
/// ///
/// If `T: !Unpin` it will not be able to move afterwards. /// If `T: !Unpin` it will not be able to move afterwards.
#[inline] #[inline]
pub fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Self> pub fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self>
where where
Error: From<E>, Error: From<E>,
{ {
UniqueArc::pin_init(init).map(|u| u.into()) UniqueArc::pin_init(init, flags).map(|u| u.into())
} }
/// Use the given initializer to in-place initialize a `T`. /// Use the given initializer to in-place initialize a `T`.
/// ///
/// This is equivalent to [`Arc<T>::pin_init`], since an [`Arc`] is always pinned. /// This is equivalent to [`Arc<T>::pin_init`], since an [`Arc`] is always pinned.
#[inline] #[inline]
pub fn init<E>(init: impl Init<T, E>) -> error::Result<Self> pub fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
where where
Error: From<E>, Error: From<E>,
{ {
UniqueArc::init(init).map(|u| u.into()) UniqueArc::init(init, flags).map(|u| u.into())
} }
} }
...@@ -565,13 +565,16 @@ pub fn new(value: T, flags: Flags) -> Result<Self, AllocError> { ...@@ -565,13 +565,16 @@ pub fn new(value: T, flags: Flags) -> Result<Self, AllocError> {
} }
/// 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>(try_init!(ArcInner { let inner = Box::try_init::<AllocError>(
// SAFETY: There are no safety requirements for this FFI call. try_init!(ArcInner {
refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), // SAFETY: There are no safety requirements for this FFI call.
data <- init::uninit::<T, AllocError>(), refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
}? AllocError))?; data <- init::uninit::<T, AllocError>(),
}? AllocError),
flags,
)?;
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 `Box` is valid.
......
...@@ -75,7 +75,7 @@ macro_rules! new_condvar { ...@@ -75,7 +75,7 @@ macro_rules! new_condvar {
/// Box::pin_init(pin_init!(Example { /// Box::pin_init(pin_init!(Example {
/// value <- new_mutex!(0), /// value <- new_mutex!(0),
/// value_changed <- new_condvar!(), /// value_changed <- new_condvar!(),
/// })) /// }), GFP_KERNEL)
/// } /// }
/// ``` /// ```
/// ///
......
...@@ -60,7 +60,7 @@ macro_rules! new_mutex { ...@@ -60,7 +60,7 @@ macro_rules! new_mutex {
/// } /// }
/// ///
/// // Allocate a boxed `Example`. /// // Allocate a boxed `Example`.
/// let e = Box::pin_init(Example::new())?; /// let e = Box::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);
......
...@@ -58,7 +58,7 @@ macro_rules! new_spinlock { ...@@ -58,7 +58,7 @@ macro_rules! new_spinlock {
/// } /// }
/// ///
/// // Allocate a boxed `Example`. /// // Allocate a boxed `Example`.
/// let e = Box::pin_init(Example::new())?; /// let e = Box::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);
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
//! Arc::pin_init(pin_init!(MyStruct { //! Arc::pin_init(pin_init!(MyStruct {
//! value, //! value,
//! work <- new_work!("MyStruct::work"), //! work <- new_work!("MyStruct::work"),
//! })) //! }), GFP_KERNEL)
//! } //! }
//! } //! }
//! //!
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
//! value_2, //! value_2,
//! work_1 <- new_work!("MyStruct::work_1"), //! work_1 <- new_work!("MyStruct::work_1"),
//! work_2 <- new_work!("MyStruct::work_2"), //! work_2 <- new_work!("MyStruct::work_2"),
//! })) //! }), GFP_KERNEL)
//! } //! }
//! } //! }
//! //!
...@@ -132,6 +132,7 @@ ...@@ -132,6 +132,7 @@
//! //!
//! C header: [`include/linux/workqueue.h`](srctree/include/linux/workqueue.h) //! C header: [`include/linux/workqueue.h`](srctree/include/linux/workqueue.h)
use crate::alloc::Flags;
use crate::{bindings, prelude::*, sync::Arc, sync::LockClassKey, types::Opaque}; use crate::{bindings, prelude::*, sync::Arc, sync::LockClassKey, types::Opaque};
use alloc::alloc::AllocError; use alloc::alloc::AllocError;
use alloc::boxed::Box; use alloc::boxed::Box;
...@@ -210,13 +211,17 @@ pub fn enqueue<W, const ID: u64>(&self, w: W) -> W::EnqueueOutput ...@@ -210,13 +211,17 @@ pub fn enqueue<W, const ID: u64>(&self, w: W) -> W::EnqueueOutput
/// Tries to spawn the given function or closure as a work item. /// Tries to spawn the given function or closure as a work item.
/// ///
/// This method can fail because it allocates memory to store the work item. /// This method can fail because it allocates memory to store the work item.
pub fn try_spawn<T: 'static + Send + FnOnce()>(&self, func: T) -> Result<(), AllocError> { pub fn try_spawn<T: 'static + Send + FnOnce()>(
&self,
flags: Flags,
func: T,
) -> Result<(), AllocError> {
let init = pin_init!(ClosureWork { let init = pin_init!(ClosureWork {
work <- new_work!("Queue::try_spawn"), work <- new_work!("Queue::try_spawn"),
func: Some(func), func: Some(func),
}); });
self.enqueue(Box::pin_init(init).map_err(|_| AllocError)?); self.enqueue(Box::pin_init(init, flags).map_err(|_| AllocError)?);
Ok(()) Ok(())
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment