request.rs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // SPDX-License-Identifier: GPL-2.0
  2. //! This module provides a wrapper for the C `struct request` type.
  3. //!
  4. //! C header: [`include/linux/blk-mq.h`](srctree/include/linux/blk-mq.h)
  5. use crate::{
  6. bindings,
  7. block::mq::Operations,
  8. error::Result,
  9. types::{ARef, AlwaysRefCounted, Opaque},
  10. };
  11. use core::{
  12. marker::PhantomData,
  13. ptr::{addr_of_mut, NonNull},
  14. sync::atomic::{AtomicU64, Ordering},
  15. };
  16. /// A wrapper around a blk-mq [`struct request`]. This represents an IO request.
  17. ///
  18. /// # Implementation details
  19. ///
  20. /// There are four states for a request that the Rust bindings care about:
  21. ///
  22. /// 1. Request is owned by block layer (refcount 0).
  23. /// 2. Request is owned by driver but with zero [`ARef`]s in existence
  24. /// (refcount 1).
  25. /// 3. Request is owned by driver with exactly one [`ARef`] in existence
  26. /// (refcount 2).
  27. /// 4. Request is owned by driver with more than one [`ARef`] in existence
  28. /// (refcount > 2).
  29. ///
  30. ///
  31. /// We need to track 1 and 2 to ensure we fail tag to request conversions for
  32. /// requests that are not owned by the driver.
  33. ///
  34. /// We need to track 3 and 4 to ensure that it is safe to end the request and hand
  35. /// back ownership to the block layer.
  36. ///
  37. /// The states are tracked through the private `refcount` field of
  38. /// `RequestDataWrapper`. This structure lives in the private data area of the C
  39. /// [`struct request`].
  40. ///
  41. /// # Invariants
  42. ///
  43. /// * `self.0` is a valid [`struct request`] created by the C portion of the
  44. /// kernel.
  45. /// * The private data area associated with this request must be an initialized
  46. /// and valid `RequestDataWrapper<T>`.
  47. /// * `self` is reference counted by atomic modification of
  48. /// `self.wrapper_ref().refcount()`.
  49. ///
  50. /// [`struct request`]: srctree/include/linux/blk-mq.h
  51. ///
  52. #[repr(transparent)]
  53. pub struct Request<T: Operations>(Opaque<bindings::request>, PhantomData<T>);
  54. impl<T: Operations> Request<T> {
  55. /// Create an [`ARef<Request>`] from a [`struct request`] pointer.
  56. ///
  57. /// # Safety
  58. ///
  59. /// * The caller must own a refcount on `ptr` that is transferred to the
  60. /// returned [`ARef`].
  61. /// * The type invariants for [`Request`] must hold for the pointee of `ptr`.
  62. ///
  63. /// [`struct request`]: srctree/include/linux/blk-mq.h
  64. pub(crate) unsafe fn aref_from_raw(ptr: *mut bindings::request) -> ARef<Self> {
  65. // INVARIANT: By the safety requirements of this function, invariants are upheld.
  66. // SAFETY: By the safety requirement of this function, we own a
  67. // reference count that we can pass to `ARef`.
  68. unsafe { ARef::from_raw(NonNull::new_unchecked(ptr as *const Self as *mut Self)) }
  69. }
  70. /// Notify the block layer that a request is going to be processed now.
  71. ///
  72. /// The block layer uses this hook to do proper initializations such as
  73. /// starting the timeout timer. It is a requirement that block device
  74. /// drivers call this function when starting to process a request.
  75. ///
  76. /// # Safety
  77. ///
  78. /// The caller must have exclusive ownership of `self`, that is
  79. /// `self.wrapper_ref().refcount() == 2`.
  80. pub(crate) unsafe fn start_unchecked(this: &ARef<Self>) {
  81. // SAFETY: By type invariant, `self.0` is a valid `struct request` and
  82. // we have exclusive access.
  83. unsafe { bindings::blk_mq_start_request(this.0.get()) };
  84. }
  85. /// Try to take exclusive ownership of `this` by dropping the refcount to 0.
  86. /// This fails if `this` is not the only [`ARef`] pointing to the underlying
  87. /// [`Request`].
  88. ///
  89. /// If the operation is successful, [`Ok`] is returned with a pointer to the
  90. /// C [`struct request`]. If the operation fails, `this` is returned in the
  91. /// [`Err`] variant.
  92. ///
  93. /// [`struct request`]: srctree/include/linux/blk-mq.h
  94. fn try_set_end(this: ARef<Self>) -> Result<*mut bindings::request, ARef<Self>> {
  95. // We can race with `TagSet::tag_to_rq`
  96. if let Err(_old) = this.wrapper_ref().refcount().compare_exchange(
  97. 2,
  98. 0,
  99. Ordering::Relaxed,
  100. Ordering::Relaxed,
  101. ) {
  102. return Err(this);
  103. }
  104. let request_ptr = this.0.get();
  105. core::mem::forget(this);
  106. Ok(request_ptr)
  107. }
  108. /// Notify the block layer that the request has been completed without errors.
  109. ///
  110. /// This function will return [`Err`] if `this` is not the only [`ARef`]
  111. /// referencing the request.
  112. pub fn end_ok(this: ARef<Self>) -> Result<(), ARef<Self>> {
  113. let request_ptr = Self::try_set_end(this)?;
  114. // SAFETY: By type invariant, `this.0` was a valid `struct request`. The
  115. // success of the call to `try_set_end` guarantees that there are no
  116. // `ARef`s pointing to this request. Therefore it is safe to hand it
  117. // back to the block layer.
  118. unsafe { bindings::blk_mq_end_request(request_ptr, bindings::BLK_STS_OK as _) };
  119. Ok(())
  120. }
  121. /// Return a pointer to the [`RequestDataWrapper`] stored in the private area
  122. /// of the request structure.
  123. ///
  124. /// # Safety
  125. ///
  126. /// - `this` must point to a valid allocation of size at least size of
  127. /// [`Self`] plus size of [`RequestDataWrapper`].
  128. pub(crate) unsafe fn wrapper_ptr(this: *mut Self) -> NonNull<RequestDataWrapper> {
  129. let request_ptr = this.cast::<bindings::request>();
  130. // SAFETY: By safety requirements for this function, `this` is a
  131. // valid allocation.
  132. let wrapper_ptr =
  133. unsafe { bindings::blk_mq_rq_to_pdu(request_ptr).cast::<RequestDataWrapper>() };
  134. // SAFETY: By C API contract, wrapper_ptr points to a valid allocation
  135. // and is not null.
  136. unsafe { NonNull::new_unchecked(wrapper_ptr) }
  137. }
  138. /// Return a reference to the [`RequestDataWrapper`] stored in the private
  139. /// area of the request structure.
  140. pub(crate) fn wrapper_ref(&self) -> &RequestDataWrapper {
  141. // SAFETY: By type invariant, `self.0` is a valid allocation. Further,
  142. // the private data associated with this request is initialized and
  143. // valid. The existence of `&self` guarantees that the private data is
  144. // valid as a shared reference.
  145. unsafe { Self::wrapper_ptr(self as *const Self as *mut Self).as_ref() }
  146. }
  147. }
  148. /// A wrapper around data stored in the private area of the C [`struct request`].
  149. ///
  150. /// [`struct request`]: srctree/include/linux/blk-mq.h
  151. pub(crate) struct RequestDataWrapper {
  152. /// The Rust request refcount has the following states:
  153. ///
  154. /// - 0: The request is owned by C block layer.
  155. /// - 1: The request is owned by Rust abstractions but there are no [`ARef`] references to it.
  156. /// - 2+: There are [`ARef`] references to the request.
  157. refcount: AtomicU64,
  158. }
  159. impl RequestDataWrapper {
  160. /// Return a reference to the refcount of the request that is embedding
  161. /// `self`.
  162. pub(crate) fn refcount(&self) -> &AtomicU64 {
  163. &self.refcount
  164. }
  165. /// Return a pointer to the refcount of the request that is embedding the
  166. /// pointee of `this`.
  167. ///
  168. /// # Safety
  169. ///
  170. /// - `this` must point to a live allocation of at least the size of `Self`.
  171. pub(crate) unsafe fn refcount_ptr(this: *mut Self) -> *mut AtomicU64 {
  172. // SAFETY: Because of the safety requirements of this function, the
  173. // field projection is safe.
  174. unsafe { addr_of_mut!((*this).refcount) }
  175. }
  176. }
  177. // SAFETY: Exclusive access is thread-safe for `Request`. `Request` has no `&mut
  178. // self` methods and `&self` methods that mutate `self` are internally
  179. // synchronized.
  180. unsafe impl<T: Operations> Send for Request<T> {}
  181. // SAFETY: Shared access is thread-safe for `Request`. `&self` methods that
  182. // mutate `self` are internally synchronized`
  183. unsafe impl<T: Operations> Sync for Request<T> {}
  184. /// Store the result of `op(target.load())` in target, returning new value of
  185. /// target.
  186. fn atomic_relaxed_op_return(target: &AtomicU64, op: impl Fn(u64) -> u64) -> u64 {
  187. let old = target.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |x| Some(op(x)));
  188. // SAFETY: Because the operation passed to `fetch_update` above always
  189. // return `Some`, `old` will always be `Ok`.
  190. let old = unsafe { old.unwrap_unchecked() };
  191. op(old)
  192. }
  193. /// Store the result of `op(target.load)` in `target` if `target.load() !=
  194. /// pred`, returning [`true`] if the target was updated.
  195. fn atomic_relaxed_op_unless(target: &AtomicU64, op: impl Fn(u64) -> u64, pred: u64) -> bool {
  196. target
  197. .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |x| {
  198. if x == pred {
  199. None
  200. } else {
  201. Some(op(x))
  202. }
  203. })
  204. .is_ok()
  205. }
  206. // SAFETY: All instances of `Request<T>` are reference counted. This
  207. // implementation of `AlwaysRefCounted` ensure that increments to the ref count
  208. // keeps the object alive in memory at least until a matching reference count
  209. // decrement is executed.
  210. unsafe impl<T: Operations> AlwaysRefCounted for Request<T> {
  211. fn inc_ref(&self) {
  212. let refcount = &self.wrapper_ref().refcount();
  213. #[cfg_attr(not(CONFIG_DEBUG_MISC), allow(unused_variables))]
  214. let updated = atomic_relaxed_op_unless(refcount, |x| x + 1, 0);
  215. #[cfg(CONFIG_DEBUG_MISC)]
  216. if !updated {
  217. panic!("Request refcount zero on clone")
  218. }
  219. }
  220. unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
  221. // SAFETY: The type invariants of `ARef` guarantee that `obj` is valid
  222. // for read.
  223. let wrapper_ptr = unsafe { Self::wrapper_ptr(obj.as_ptr()).as_ptr() };
  224. // SAFETY: The type invariant of `Request` guarantees that the private
  225. // data area is initialized and valid.
  226. let refcount = unsafe { &*RequestDataWrapper::refcount_ptr(wrapper_ptr) };
  227. #[cfg_attr(not(CONFIG_DEBUG_MISC), allow(unused_variables))]
  228. let new_refcount = atomic_relaxed_op_return(refcount, |x| x - 1);
  229. #[cfg(CONFIG_DEBUG_MISC)]
  230. if new_refcount == 0 {
  231. panic!("Request reached refcount zero in Rust abstractions");
  232. }
  233. }
  234. }