workqueue.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. // SPDX-License-Identifier: GPL-2.0
  2. //! Work queues.
  3. //!
  4. //! This file has two components: The raw work item API, and the safe work item API.
  5. //!
  6. //! One pattern that is used in both APIs is the `ID` const generic, which exists to allow a single
  7. //! type to define multiple `work_struct` fields. This is done by choosing an id for each field,
  8. //! and using that id to specify which field you wish to use. (The actual value doesn't matter, as
  9. //! long as you use different values for different fields of the same struct.) Since these IDs are
  10. //! generic, they are used only at compile-time, so they shouldn't exist in the final binary.
  11. //!
  12. //! # The raw API
  13. //!
  14. //! The raw API consists of the [`RawWorkItem`] trait, where the work item needs to provide an
  15. //! arbitrary function that knows how to enqueue the work item. It should usually not be used
  16. //! directly, but if you want to, you can use it without using the pieces from the safe API.
  17. //!
  18. //! # The safe API
  19. //!
  20. //! The safe API is used via the [`Work`] struct and [`WorkItem`] traits. Furthermore, it also
  21. //! includes a trait called [`WorkItemPointer`], which is usually not used directly by the user.
  22. //!
  23. //! * The [`Work`] struct is the Rust wrapper for the C `work_struct` type.
  24. //! * The [`WorkItem`] trait is implemented for structs that can be enqueued to a workqueue.
  25. //! * The [`WorkItemPointer`] trait is implemented for the pointer type that points at a something
  26. //! that implements [`WorkItem`].
  27. //!
  28. //! ## Example
  29. //!
  30. //! This example defines a struct that holds an integer and can be scheduled on the workqueue. When
  31. //! the struct is executed, it will print the integer. Since there is only one `work_struct` field,
  32. //! we do not need to specify ids for the fields.
  33. //!
  34. //! ```
  35. //! use kernel::sync::Arc;
  36. //! use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
  37. //!
  38. //! #[pin_data]
  39. //! struct MyStruct {
  40. //! value: i32,
  41. //! #[pin]
  42. //! work: Work<MyStruct>,
  43. //! }
  44. //!
  45. //! impl_has_work! {
  46. //! impl HasWork<Self> for MyStruct { self.work }
  47. //! }
  48. //!
  49. //! impl MyStruct {
  50. //! fn new(value: i32) -> Result<Arc<Self>> {
  51. //! Arc::pin_init(pin_init!(MyStruct {
  52. //! value,
  53. //! work <- new_work!("MyStruct::work"),
  54. //! }), GFP_KERNEL)
  55. //! }
  56. //! }
  57. //!
  58. //! impl WorkItem for MyStruct {
  59. //! type Pointer = Arc<MyStruct>;
  60. //!
  61. //! fn run(this: Arc<MyStruct>) {
  62. //! pr_info!("The value is: {}", this.value);
  63. //! }
  64. //! }
  65. //!
  66. //! /// This method will enqueue the struct for execution on the system workqueue, where its value
  67. //! /// will be printed.
  68. //! fn print_later(val: Arc<MyStruct>) {
  69. //! let _ = workqueue::system().enqueue(val);
  70. //! }
  71. //! ```
  72. //!
  73. //! The following example shows how multiple `work_struct` fields can be used:
  74. //!
  75. //! ```
  76. //! use kernel::sync::Arc;
  77. //! use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
  78. //!
  79. //! #[pin_data]
  80. //! struct MyStruct {
  81. //! value_1: i32,
  82. //! value_2: i32,
  83. //! #[pin]
  84. //! work_1: Work<MyStruct, 1>,
  85. //! #[pin]
  86. //! work_2: Work<MyStruct, 2>,
  87. //! }
  88. //!
  89. //! impl_has_work! {
  90. //! impl HasWork<Self, 1> for MyStruct { self.work_1 }
  91. //! impl HasWork<Self, 2> for MyStruct { self.work_2 }
  92. //! }
  93. //!
  94. //! impl MyStruct {
  95. //! fn new(value_1: i32, value_2: i32) -> Result<Arc<Self>> {
  96. //! Arc::pin_init(pin_init!(MyStruct {
  97. //! value_1,
  98. //! value_2,
  99. //! work_1 <- new_work!("MyStruct::work_1"),
  100. //! work_2 <- new_work!("MyStruct::work_2"),
  101. //! }), GFP_KERNEL)
  102. //! }
  103. //! }
  104. //!
  105. //! impl WorkItem<1> for MyStruct {
  106. //! type Pointer = Arc<MyStruct>;
  107. //!
  108. //! fn run(this: Arc<MyStruct>) {
  109. //! pr_info!("The value is: {}", this.value_1);
  110. //! }
  111. //! }
  112. //!
  113. //! impl WorkItem<2> for MyStruct {
  114. //! type Pointer = Arc<MyStruct>;
  115. //!
  116. //! fn run(this: Arc<MyStruct>) {
  117. //! pr_info!("The second value is: {}", this.value_2);
  118. //! }
  119. //! }
  120. //!
  121. //! fn print_1_later(val: Arc<MyStruct>) {
  122. //! let _ = workqueue::system().enqueue::<Arc<MyStruct>, 1>(val);
  123. //! }
  124. //!
  125. //! fn print_2_later(val: Arc<MyStruct>) {
  126. //! let _ = workqueue::system().enqueue::<Arc<MyStruct>, 2>(val);
  127. //! }
  128. //! ```
  129. //!
  130. //! C header: [`include/linux/workqueue.h`](srctree/include/linux/workqueue.h)
  131. use crate::alloc::{AllocError, Flags};
  132. use crate::{prelude::*, sync::Arc, sync::LockClassKey, types::Opaque};
  133. use core::marker::PhantomData;
  134. /// Creates a [`Work`] initialiser with the given name and a newly-created lock class.
  135. #[macro_export]
  136. macro_rules! new_work {
  137. ($($name:literal)?) => {
  138. $crate::workqueue::Work::new($crate::optional_name!($($name)?), $crate::static_lock_class!())
  139. };
  140. }
  141. pub use new_work;
  142. /// A kernel work queue.
  143. ///
  144. /// Wraps the kernel's C `struct workqueue_struct`.
  145. ///
  146. /// It allows work items to be queued to run on thread pools managed by the kernel. Several are
  147. /// always available, for example, `system`, `system_highpri`, `system_long`, etc.
  148. #[repr(transparent)]
  149. pub struct Queue(Opaque<bindings::workqueue_struct>);
  150. // SAFETY: Accesses to workqueues used by [`Queue`] are thread-safe.
  151. unsafe impl Send for Queue {}
  152. // SAFETY: Accesses to workqueues used by [`Queue`] are thread-safe.
  153. unsafe impl Sync for Queue {}
  154. impl Queue {
  155. /// Use the provided `struct workqueue_struct` with Rust.
  156. ///
  157. /// # Safety
  158. ///
  159. /// The caller must ensure that the provided raw pointer is not dangling, that it points at a
  160. /// valid workqueue, and that it remains valid until the end of `'a`.
  161. pub unsafe fn from_raw<'a>(ptr: *const bindings::workqueue_struct) -> &'a Queue {
  162. // SAFETY: The `Queue` type is `#[repr(transparent)]`, so the pointer cast is valid. The
  163. // caller promises that the pointer is not dangling.
  164. unsafe { &*(ptr as *const Queue) }
  165. }
  166. /// Enqueues a work item.
  167. ///
  168. /// This may fail if the work item is already enqueued in a workqueue.
  169. ///
  170. /// The work item will be submitted using `WORK_CPU_UNBOUND`.
  171. pub fn enqueue<W, const ID: u64>(&self, w: W) -> W::EnqueueOutput
  172. where
  173. W: RawWorkItem<ID> + Send + 'static,
  174. {
  175. let queue_ptr = self.0.get();
  176. // SAFETY: We only return `false` if the `work_struct` is already in a workqueue. The other
  177. // `__enqueue` requirements are not relevant since `W` is `Send` and static.
  178. //
  179. // The call to `bindings::queue_work_on` will dereference the provided raw pointer, which
  180. // is ok because `__enqueue` guarantees that the pointer is valid for the duration of this
  181. // closure.
  182. //
  183. // Furthermore, if the C workqueue code accesses the pointer after this call to
  184. // `__enqueue`, then the work item was successfully enqueued, and `bindings::queue_work_on`
  185. // will have returned true. In this case, `__enqueue` promises that the raw pointer will
  186. // stay valid until we call the function pointer in the `work_struct`, so the access is ok.
  187. unsafe {
  188. w.__enqueue(move |work_ptr| {
  189. bindings::queue_work_on(
  190. bindings::wq_misc_consts_WORK_CPU_UNBOUND as _,
  191. queue_ptr,
  192. work_ptr,
  193. )
  194. })
  195. }
  196. }
  197. /// Tries to spawn the given function or closure as a work item.
  198. ///
  199. /// This method can fail because it allocates memory to store the work item.
  200. pub fn try_spawn<T: 'static + Send + FnOnce()>(
  201. &self,
  202. flags: Flags,
  203. func: T,
  204. ) -> Result<(), AllocError> {
  205. let init = pin_init!(ClosureWork {
  206. work <- new_work!("Queue::try_spawn"),
  207. func: Some(func),
  208. });
  209. self.enqueue(KBox::pin_init(init, flags).map_err(|_| AllocError)?);
  210. Ok(())
  211. }
  212. }
  213. /// A helper type used in [`try_spawn`].
  214. ///
  215. /// [`try_spawn`]: Queue::try_spawn
  216. #[pin_data]
  217. struct ClosureWork<T> {
  218. #[pin]
  219. work: Work<ClosureWork<T>>,
  220. func: Option<T>,
  221. }
  222. impl<T> ClosureWork<T> {
  223. fn project(self: Pin<&mut Self>) -> &mut Option<T> {
  224. // SAFETY: The `func` field is not structurally pinned.
  225. unsafe { &mut self.get_unchecked_mut().func }
  226. }
  227. }
  228. impl<T: FnOnce()> WorkItem for ClosureWork<T> {
  229. type Pointer = Pin<KBox<Self>>;
  230. fn run(mut this: Pin<KBox<Self>>) {
  231. if let Some(func) = this.as_mut().project().take() {
  232. (func)()
  233. }
  234. }
  235. }
  236. /// A raw work item.
  237. ///
  238. /// This is the low-level trait that is designed for being as general as possible.
  239. ///
  240. /// The `ID` parameter to this trait exists so that a single type can provide multiple
  241. /// implementations of this trait. For example, if a struct has multiple `work_struct` fields, then
  242. /// you will implement this trait once for each field, using a different id for each field. The
  243. /// actual value of the id is not important as long as you use different ids for different fields
  244. /// of the same struct. (Fields of different structs need not use different ids.)
  245. ///
  246. /// Note that the id is used only to select the right method to call during compilation. It won't be
  247. /// part of the final executable.
  248. ///
  249. /// # Safety
  250. ///
  251. /// Implementers must ensure that any pointers passed to a `queue_work_on` closure by [`__enqueue`]
  252. /// remain valid for the duration specified in the guarantees section of the documentation for
  253. /// [`__enqueue`].
  254. ///
  255. /// [`__enqueue`]: RawWorkItem::__enqueue
  256. pub unsafe trait RawWorkItem<const ID: u64> {
  257. /// The return type of [`Queue::enqueue`].
  258. type EnqueueOutput;
  259. /// Enqueues this work item on a queue using the provided `queue_work_on` method.
  260. ///
  261. /// # Guarantees
  262. ///
  263. /// If this method calls the provided closure, then the raw pointer is guaranteed to point at a
  264. /// valid `work_struct` for the duration of the call to the closure. If the closure returns
  265. /// true, then it is further guaranteed that the pointer remains valid until someone calls the
  266. /// function pointer stored in the `work_struct`.
  267. ///
  268. /// # Safety
  269. ///
  270. /// The provided closure may only return `false` if the `work_struct` is already in a workqueue.
  271. ///
  272. /// If the work item type is annotated with any lifetimes, then you must not call the function
  273. /// pointer after any such lifetime expires. (Never calling the function pointer is okay.)
  274. ///
  275. /// If the work item type is not [`Send`], then the function pointer must be called on the same
  276. /// thread as the call to `__enqueue`.
  277. unsafe fn __enqueue<F>(self, queue_work_on: F) -> Self::EnqueueOutput
  278. where
  279. F: FnOnce(*mut bindings::work_struct) -> bool;
  280. }
  281. /// Defines the method that should be called directly when a work item is executed.
  282. ///
  283. /// This trait is implemented by `Pin<KBox<T>>` and [`Arc<T>`], and is mainly intended to be
  284. /// implemented for smart pointer types. For your own structs, you would implement [`WorkItem`]
  285. /// instead. The [`run`] method on this trait will usually just perform the appropriate
  286. /// `container_of` translation and then call into the [`run`][WorkItem::run] method from the
  287. /// [`WorkItem`] trait.
  288. ///
  289. /// This trait is used when the `work_struct` field is defined using the [`Work`] helper.
  290. ///
  291. /// # Safety
  292. ///
  293. /// Implementers must ensure that [`__enqueue`] uses a `work_struct` initialized with the [`run`]
  294. /// method of this trait as the function pointer.
  295. ///
  296. /// [`__enqueue`]: RawWorkItem::__enqueue
  297. /// [`run`]: WorkItemPointer::run
  298. pub unsafe trait WorkItemPointer<const ID: u64>: RawWorkItem<ID> {
  299. /// Run this work item.
  300. ///
  301. /// # Safety
  302. ///
  303. /// The provided `work_struct` pointer must originate from a previous call to [`__enqueue`]
  304. /// where the `queue_work_on` closure returned true, and the pointer must still be valid.
  305. ///
  306. /// [`__enqueue`]: RawWorkItem::__enqueue
  307. unsafe extern "C" fn run(ptr: *mut bindings::work_struct);
  308. }
  309. /// Defines the method that should be called when this work item is executed.
  310. ///
  311. /// This trait is used when the `work_struct` field is defined using the [`Work`] helper.
  312. pub trait WorkItem<const ID: u64 = 0> {
  313. /// The pointer type that this struct is wrapped in. This will typically be `Arc<Self>` or
  314. /// `Pin<KBox<Self>>`.
  315. type Pointer: WorkItemPointer<ID>;
  316. /// The method that should be called when this work item is executed.
  317. fn run(this: Self::Pointer);
  318. }
  319. /// Links for a work item.
  320. ///
  321. /// This struct contains a function pointer to the [`run`] function from the [`WorkItemPointer`]
  322. /// trait, and defines the linked list pointers necessary to enqueue a work item in a workqueue.
  323. ///
  324. /// Wraps the kernel's C `struct work_struct`.
  325. ///
  326. /// This is a helper type used to associate a `work_struct` with the [`WorkItem`] that uses it.
  327. ///
  328. /// [`run`]: WorkItemPointer::run
  329. #[pin_data]
  330. #[repr(transparent)]
  331. pub struct Work<T: ?Sized, const ID: u64 = 0> {
  332. #[pin]
  333. work: Opaque<bindings::work_struct>,
  334. _inner: PhantomData<T>,
  335. }
  336. // SAFETY: Kernel work items are usable from any thread.
  337. //
  338. // We do not need to constrain `T` since the work item does not actually contain a `T`.
  339. unsafe impl<T: ?Sized, const ID: u64> Send for Work<T, ID> {}
  340. // SAFETY: Kernel work items are usable from any thread.
  341. //
  342. // We do not need to constrain `T` since the work item does not actually contain a `T`.
  343. unsafe impl<T: ?Sized, const ID: u64> Sync for Work<T, ID> {}
  344. impl<T: ?Sized, const ID: u64> Work<T, ID> {
  345. /// Creates a new instance of [`Work`].
  346. #[inline]
  347. pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self>
  348. where
  349. T: WorkItem<ID>,
  350. {
  351. pin_init!(Self {
  352. work <- Opaque::ffi_init(|slot| {
  353. // SAFETY: The `WorkItemPointer` implementation promises that `run` can be used as
  354. // the work item function.
  355. unsafe {
  356. bindings::init_work_with_key(
  357. slot,
  358. Some(T::Pointer::run),
  359. false,
  360. name.as_char_ptr(),
  361. key.as_ptr(),
  362. )
  363. }
  364. }),
  365. _inner: PhantomData,
  366. })
  367. }
  368. /// Get a pointer to the inner `work_struct`.
  369. ///
  370. /// # Safety
  371. ///
  372. /// The provided pointer must not be dangling and must be properly aligned. (But the memory
  373. /// need not be initialized.)
  374. #[inline]
  375. pub unsafe fn raw_get(ptr: *const Self) -> *mut bindings::work_struct {
  376. // SAFETY: The caller promises that the pointer is aligned and not dangling.
  377. //
  378. // A pointer cast would also be ok due to `#[repr(transparent)]`. We use `addr_of!` so that
  379. // the compiler does not complain that the `work` field is unused.
  380. unsafe { Opaque::raw_get(core::ptr::addr_of!((*ptr).work)) }
  381. }
  382. }
  383. /// Declares that a type has a [`Work<T, ID>`] field.
  384. ///
  385. /// The intended way of using this trait is via the [`impl_has_work!`] macro. You can use the macro
  386. /// like this:
  387. ///
  388. /// ```no_run
  389. /// use kernel::workqueue::{impl_has_work, Work};
  390. ///
  391. /// struct MyWorkItem {
  392. /// work_field: Work<MyWorkItem, 1>,
  393. /// }
  394. ///
  395. /// impl_has_work! {
  396. /// impl HasWork<MyWorkItem, 1> for MyWorkItem { self.work_field }
  397. /// }
  398. /// ```
  399. ///
  400. /// Note that since the [`Work`] type is annotated with an id, you can have several `work_struct`
  401. /// fields by using a different id for each one.
  402. ///
  403. /// # Safety
  404. ///
  405. /// The [`OFFSET`] constant must be the offset of a field in `Self` of type [`Work<T, ID>`]. The
  406. /// methods on this trait must have exactly the behavior that the definitions given below have.
  407. ///
  408. /// [`impl_has_work!`]: crate::impl_has_work
  409. /// [`OFFSET`]: HasWork::OFFSET
  410. pub unsafe trait HasWork<T, const ID: u64 = 0> {
  411. /// The offset of the [`Work<T, ID>`] field.
  412. const OFFSET: usize;
  413. /// Returns the offset of the [`Work<T, ID>`] field.
  414. ///
  415. /// This method exists because the [`OFFSET`] constant cannot be accessed if the type is not
  416. /// [`Sized`].
  417. ///
  418. /// [`OFFSET`]: HasWork::OFFSET
  419. #[inline]
  420. fn get_work_offset(&self) -> usize {
  421. Self::OFFSET
  422. }
  423. /// Returns a pointer to the [`Work<T, ID>`] field.
  424. ///
  425. /// # Safety
  426. ///
  427. /// The provided pointer must point at a valid struct of type `Self`.
  428. #[inline]
  429. unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID> {
  430. // SAFETY: The caller promises that the pointer is valid.
  431. unsafe { (ptr as *mut u8).add(Self::OFFSET) as *mut Work<T, ID> }
  432. }
  433. /// Returns a pointer to the struct containing the [`Work<T, ID>`] field.
  434. ///
  435. /// # Safety
  436. ///
  437. /// The pointer must point at a [`Work<T, ID>`] field in a struct of type `Self`.
  438. #[inline]
  439. unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self
  440. where
  441. Self: Sized,
  442. {
  443. // SAFETY: The caller promises that the pointer points at a field of the right type in the
  444. // right kind of struct.
  445. unsafe { (ptr as *mut u8).sub(Self::OFFSET) as *mut Self }
  446. }
  447. }
  448. /// Used to safely implement the [`HasWork<T, ID>`] trait.
  449. ///
  450. /// # Examples
  451. ///
  452. /// ```
  453. /// use kernel::sync::Arc;
  454. /// use kernel::workqueue::{self, impl_has_work, Work};
  455. ///
  456. /// struct MyStruct<'a, T, const N: usize> {
  457. /// work_field: Work<MyStruct<'a, T, N>, 17>,
  458. /// f: fn(&'a [T; N]),
  459. /// }
  460. ///
  461. /// impl_has_work! {
  462. /// impl{'a, T, const N: usize} HasWork<MyStruct<'a, T, N>, 17>
  463. /// for MyStruct<'a, T, N> { self.work_field }
  464. /// }
  465. /// ```
  466. #[macro_export]
  467. macro_rules! impl_has_work {
  468. ($(impl$({$($generics:tt)*})?
  469. HasWork<$work_type:ty $(, $id:tt)?>
  470. for $self:ty
  471. { self.$field:ident }
  472. )*) => {$(
  473. // SAFETY: The implementation of `raw_get_work` only compiles if the field has the right
  474. // type.
  475. unsafe impl$(<$($generics)+>)? $crate::workqueue::HasWork<$work_type $(, $id)?> for $self {
  476. const OFFSET: usize = ::core::mem::offset_of!(Self, $field) as usize;
  477. #[inline]
  478. unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crate::workqueue::Work<$work_type $(, $id)?> {
  479. // SAFETY: The caller promises that the pointer is not dangling.
  480. unsafe {
  481. ::core::ptr::addr_of_mut!((*ptr).$field)
  482. }
  483. }
  484. }
  485. )*};
  486. }
  487. pub use impl_has_work;
  488. impl_has_work! {
  489. impl{T} HasWork<Self> for ClosureWork<T> { self.work }
  490. }
  491. // SAFETY: TODO.
  492. unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
  493. where
  494. T: WorkItem<ID, Pointer = Self>,
  495. T: HasWork<T, ID>,
  496. {
  497. unsafe extern "C" fn run(ptr: *mut bindings::work_struct) {
  498. // The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
  499. let ptr = ptr as *mut Work<T, ID>;
  500. // SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`.
  501. let ptr = unsafe { T::work_container_of(ptr) };
  502. // SAFETY: This pointer comes from `Arc::into_raw` and we've been given back ownership.
  503. let arc = unsafe { Arc::from_raw(ptr) };
  504. T::run(arc)
  505. }
  506. }
  507. // SAFETY: TODO.
  508. unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
  509. where
  510. T: WorkItem<ID, Pointer = Self>,
  511. T: HasWork<T, ID>,
  512. {
  513. type EnqueueOutput = Result<(), Self>;
  514. unsafe fn __enqueue<F>(self, queue_work_on: F) -> Self::EnqueueOutput
  515. where
  516. F: FnOnce(*mut bindings::work_struct) -> bool,
  517. {
  518. // Casting between const and mut is not a problem as long as the pointer is a raw pointer.
  519. let ptr = Arc::into_raw(self).cast_mut();
  520. // SAFETY: Pointers into an `Arc` point at a valid value.
  521. let work_ptr = unsafe { T::raw_get_work(ptr) };
  522. // SAFETY: `raw_get_work` returns a pointer to a valid value.
  523. let work_ptr = unsafe { Work::raw_get(work_ptr) };
  524. if queue_work_on(work_ptr) {
  525. Ok(())
  526. } else {
  527. // SAFETY: The work queue has not taken ownership of the pointer.
  528. Err(unsafe { Arc::from_raw(ptr) })
  529. }
  530. }
  531. }
  532. // SAFETY: TODO.
  533. unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<KBox<T>>
  534. where
  535. T: WorkItem<ID, Pointer = Self>,
  536. T: HasWork<T, ID>,
  537. {
  538. unsafe extern "C" fn run(ptr: *mut bindings::work_struct) {
  539. // The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
  540. let ptr = ptr as *mut Work<T, ID>;
  541. // SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`.
  542. let ptr = unsafe { T::work_container_of(ptr) };
  543. // SAFETY: This pointer comes from `Arc::into_raw` and we've been given back ownership.
  544. let boxed = unsafe { KBox::from_raw(ptr) };
  545. // SAFETY: The box was already pinned when it was enqueued.
  546. let pinned = unsafe { Pin::new_unchecked(boxed) };
  547. T::run(pinned)
  548. }
  549. }
  550. // SAFETY: TODO.
  551. unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<KBox<T>>
  552. where
  553. T: WorkItem<ID, Pointer = Self>,
  554. T: HasWork<T, ID>,
  555. {
  556. type EnqueueOutput = ();
  557. unsafe fn __enqueue<F>(self, queue_work_on: F) -> Self::EnqueueOutput
  558. where
  559. F: FnOnce(*mut bindings::work_struct) -> bool,
  560. {
  561. // SAFETY: We're not going to move `self` or any of its fields, so its okay to temporarily
  562. // remove the `Pin` wrapper.
  563. let boxed = unsafe { Pin::into_inner_unchecked(self) };
  564. let ptr = KBox::into_raw(boxed);
  565. // SAFETY: Pointers into a `KBox` point at a valid value.
  566. let work_ptr = unsafe { T::raw_get_work(ptr) };
  567. // SAFETY: `raw_get_work` returns a pointer to a valid value.
  568. let work_ptr = unsafe { Work::raw_get(work_ptr) };
  569. if !queue_work_on(work_ptr) {
  570. // SAFETY: This method requires exclusive ownership of the box, so it cannot be in a
  571. // workqueue.
  572. unsafe { ::core::hint::unreachable_unchecked() }
  573. }
  574. }
  575. }
  576. /// Returns the system work queue (`system_wq`).
  577. ///
  578. /// It is the one used by `schedule[_delayed]_work[_on]()`. Multi-CPU multi-threaded. There are
  579. /// users which expect relatively short queue flush time.
  580. ///
  581. /// Callers shouldn't queue work items which can run for too long.
  582. pub fn system() -> &'static Queue {
  583. // SAFETY: `system_wq` is a C global, always available.
  584. unsafe { Queue::from_raw(bindings::system_wq) }
  585. }
  586. /// Returns the system high-priority work queue (`system_highpri_wq`).
  587. ///
  588. /// It is similar to the one returned by [`system`] but for work items which require higher
  589. /// scheduling priority.
  590. pub fn system_highpri() -> &'static Queue {
  591. // SAFETY: `system_highpri_wq` is a C global, always available.
  592. unsafe { Queue::from_raw(bindings::system_highpri_wq) }
  593. }
  594. /// Returns the system work queue for potentially long-running work items (`system_long_wq`).
  595. ///
  596. /// It is similar to the one returned by [`system`] but may host long running work items. Queue
  597. /// flushing might take relatively long.
  598. pub fn system_long() -> &'static Queue {
  599. // SAFETY: `system_long_wq` is a C global, always available.
  600. unsafe { Queue::from_raw(bindings::system_long_wq) }
  601. }
  602. /// Returns the system unbound work queue (`system_unbound_wq`).
  603. ///
  604. /// Workers are not bound to any specific CPU, not concurrency managed, and all queued work items
  605. /// are executed immediately as long as `max_active` limit is not reached and resources are
  606. /// available.
  607. pub fn system_unbound() -> &'static Queue {
  608. // SAFETY: `system_unbound_wq` is a C global, always available.
  609. unsafe { Queue::from_raw(bindings::system_unbound_wq) }
  610. }
  611. /// Returns the system freezable work queue (`system_freezable_wq`).
  612. ///
  613. /// It is equivalent to the one returned by [`system`] except that it's freezable.
  614. ///
  615. /// A freezable workqueue participates in the freeze phase of the system suspend operations. Work
  616. /// items on the workqueue are drained and no new work item starts execution until thawed.
  617. pub fn system_freezable() -> &'static Queue {
  618. // SAFETY: `system_freezable_wq` is a C global, always available.
  619. unsafe { Queue::from_raw(bindings::system_freezable_wq) }
  620. }
  621. /// Returns the system power-efficient work queue (`system_power_efficient_wq`).
  622. ///
  623. /// It is inclined towards saving power and is converted to "unbound" variants if the
  624. /// `workqueue.power_efficient` kernel parameter is specified; otherwise, it is similar to the one
  625. /// returned by [`system`].
  626. pub fn system_power_efficient() -> &'static Queue {
  627. // SAFETY: `system_power_efficient_wq` is a C global, always available.
  628. unsafe { Queue::from_raw(bindings::system_power_efficient_wq) }
  629. }
  630. /// Returns the system freezable power-efficient work queue (`system_freezable_power_efficient_wq`).
  631. ///
  632. /// It is similar to the one returned by [`system_power_efficient`] except that is freezable.
  633. ///
  634. /// A freezable workqueue participates in the freeze phase of the system suspend operations. Work
  635. /// items on the workqueue are drained and no new work item starts execution until thawed.
  636. pub fn system_freezable_power_efficient() -> &'static Queue {
  637. // SAFETY: `system_freezable_power_efficient_wq` is a C global, always available.
  638. unsafe { Queue::from_raw(bindings::system_freezable_power_efficient_wq) }
  639. }