diff --git a/Documentation/rust/coding-guidelines.rst b/Documentation/rust/coding-guidelines.rst index 05542840b16cca..23355e53406648 100644 --- a/Documentation/rust/coding-guidelines.rst +++ b/Documentation/rust/coding-guidelines.rst @@ -162,7 +162,7 @@ in the kernel: a section called ``# Examples``. - Rust items (functions, types, constants...) must be linked appropriately - (``rustdoc`` will create a link automatically). + by wrapping them with square brackets (e.g., ``[`Foo::bar()`]``). - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment describing why the code inside is sound. diff --git a/Makefile b/Makefile index 68ebd6d6b444df..e8613a6a999f1c 100644 --- a/Makefile +++ b/Makefile @@ -457,6 +457,7 @@ export rust_common_flags := --edition=2021 \ -Wclippy::needless_continue \ -Wclippy::no_mangle_with_rust_abi \ -Wclippy::dbg_macro +export rustdoc_common_flags := --document-private-items KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ $(HOSTCFLAGS) -I $(srctree)/scripts/include diff --git a/rust/Makefile b/rust/Makefile index e13d14ec5fe74c..9a732faf037f6a 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -61,7 +61,8 @@ alloc-cfgs = \ quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ + $(RUSTDOC) $(rustdoc_common_flags) \ + $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ $(rustc_target_flags) -L$(objtree)/$(obj) \ -Zunstable-options --generate-link-to-definition \ --output $(rustdoc_output) \ @@ -149,7 +150,7 @@ rusttestlib-uapi: $(src)/uapi/lib.rs FORCE quiet_cmd_rustdoc_test = RUSTDOC T $< cmd_rustdoc_test = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) --test $(rust_common_flags) \ + $(RUSTDOC) $(rustdoc_common_flags) --test $(rust_common_flags) \ @$(objtree)/include/generated/rustc_cfg \ $(rustc_target_flags) $(rustdoc_test_target_flags) \ $(rustdoc_test_quiet) \ @@ -161,7 +162,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< rm -rf $(objtree)/$(obj)/test/doctests/kernel; \ mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) --test $(rust_flags) \ + $(RUSTDOC) $(rustdoc_common_flags) --test $(rust_flags) \ -L$(objtree)/$(obj) --extern alloc --extern kernel \ --extern build_error --extern macros \ --extern bindings --extern uapi \ diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request.rs index a0e22827f3f4ec..32f9804664efb4 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -16,50 +16,56 @@ use core::{ sync::atomic::{AtomicU64, Ordering}, }; -/// A wrapper around a blk-mq `struct request`. This represents an IO request. +#[allow(rustdoc::private_intra_doc_links)] +/// A wrapper around a blk-mq [`struct request`]. This represents an IO request. /// /// # Implementation details /// /// There are four states for a request that the Rust bindings care about: /// -/// A) Request is owned by block layer (refcount 0) -/// B) Request is owned by driver but with zero `ARef`s in existence +/// 1. Request is owned by block layer (refcount 0) +/// 2. Request is owned by driver but with zero [`ARef`]s in existence /// (refcount 1) -/// C) Request is owned by driver with exactly one `ARef` in existence +/// 3. Request is owned by driver with exactly one [`ARef`] in existence /// (refcount 2) -/// D) Request is owned by driver with more than one `ARef` in existence +/// 4. Request is owned by driver with more than one [`ARef`] in existence /// (refcount > 2) /// /// -/// We need to track A and B to ensure we fail tag to request conversions for +/// We need to track 1 and 2 to ensure we fail tag to request conversions for /// requests that are not owned by the driver. /// -/// We need to track C and D to ensure that it is safe to end the request and hand +/// We need to track 3 and 4 to ensure that it is safe to end the request and hand /// back ownership to the block layer. /// /// The states are tracked through the private `refcount` field of -/// `RequestDataWrapper`. This structure lives in the private data area of the C -/// `struct request`. +/// [`RequestDataWrapper`]. This structure lives in the private data area of the C +/// [`struct request`]. /// /// # Invariants /// -/// * `self.0` is a valid `struct request` created by the C portion of the kernel. +/// * `self.0` is a valid [`struct request`] created by the C portion of the +/// kernel. /// * The private data area associated with this request must be an initialized -/// and valid `RequestDataWrapper`. +/// and valid [`RequestDataWrapper`]. /// * `self` is reference counted by atomic modification of -/// self.wrapper_ref().refcount(). +/// `self.wrapper_ref().refcount()`. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h /// #[repr(transparent)] pub struct Request(Opaque, PhantomData); impl Request { - /// Create an `ARef` from a `struct request` pointer. + /// Create an [`ARef`] from a [`struct request`] pointer. /// /// # Safety /// /// * The caller must own a refcount on `ptr` that is transferred to the - /// returned `ARef`. - /// * The type invariants for `Request` must hold for the pointee of `ptr`. + /// returned [`ARef`]. + /// * The type invariants for [`Request`] must hold for the pointee of `ptr`. + /// + /// [`struct request`]: srctree/include/linux/blk-mq.h pub(crate) unsafe fn aref_from_raw(ptr: *mut bindings::request) -> ARef { // INVARIANT: By the safety requirements of this function, invariants are upheld. // SAFETY: By the safety requirement of this function, we own a @@ -84,12 +90,14 @@ impl Request { } /// Try to take exclusive ownership of `this` by dropping the refcount to 0. - /// This fails if `this` is not the only `ARef` pointing to the underlying - /// `Request`. + /// This fails if `this` is not the only [`ARef`] pointing to the underlying + /// [`Request`]. /// - /// If the operation is successful, `Ok` is returned with a pointer to the - /// C `struct request`. If the operation fails, `this` is returned in the - /// `Err` variant. + /// If the operation is successful, [`Ok`] is returned with a pointer to the + /// C [`struct request`]. If the operation fails, `this` is returned in the + /// [`Err`] variant. + /// + /// [`struct request`]: srctree/include/linux/blk-mq.h fn try_set_end(this: ARef) -> Result<*mut bindings::request, ARef> { // We can race with `TagSet::tag_to_rq` if let Err(_old) = this.wrapper_ref().refcount().compare_exchange( @@ -109,7 +117,7 @@ impl Request { /// Notify the block layer that the request has been completed without errors. /// - /// This function will return `Err` if `this` is not the only `ARef` + /// This function will return [`Err`] if `this` is not the only [`ARef`] /// referencing the request. pub fn end_ok(this: ARef) -> Result<(), ARef> { let request_ptr = Self::try_set_end(this)?; @@ -123,13 +131,13 @@ impl Request { Ok(()) } - /// Return a pointer to the `RequestDataWrapper` stored in the private area + /// Return a pointer to the [`RequestDataWrapper`] stored in the private area /// of the request structure. /// /// # Safety /// /// - `this` must point to a valid allocation of size at least size of - /// `Self` plus size of `RequestDataWrapper`. + /// [`Self`] plus size of [`RequestDataWrapper`]. pub(crate) unsafe fn wrapper_ptr(this: *mut Self) -> NonNull { let request_ptr = this.cast::(); // SAFETY: By safety requirements for this function, `this` is a @@ -141,7 +149,7 @@ impl Request { unsafe { NonNull::new_unchecked(wrapper_ptr) } } - /// Return a reference to the `RequestDataWrapper` stored in the private + /// Return a reference to the [`RequestDataWrapper`] stored in the private /// area of the request structure. pub(crate) fn wrapper_ref(&self) -> &RequestDataWrapper { // SAFETY: By type invariant, `self.0` is a valid allocation. Further, @@ -152,13 +160,15 @@ impl Request { } } -/// A wrapper around data stored in the private area of the C `struct request`. +/// A wrapper around data stored in the private area of the C [`struct request`]. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h pub(crate) struct RequestDataWrapper { /// The Rust request refcount has the following states: /// /// - 0: The request is owned by C block layer. - /// - 1: The request is owned by Rust abstractions but there are no ARef references to it. - /// - 2+: There are `ARef` references to the request. + /// - 1: The request is owned by Rust abstractions but there are no [ARef] references to it. + /// - 2+: There are [`ARef`] references to the request. refcount: AtomicU64, } @@ -204,7 +214,7 @@ fn atomic_relaxed_op_return(target: &AtomicU64, op: impl Fn(u64) -> u64) -> u64 } /// Store the result of `op(target.load)` in `target` if `target.load() != -/// pred`, returning true if the target was updated. +/// pred`, returning `true` if the target was updated. fn atomic_relaxed_op_unless(target: &AtomicU64, op: impl Fn(u64) -> u64, pred: u64) -> bool { target .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |x| {