Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: sync: Clean up LockClassKey and its docs

Several aspects of the code and documentation for this type is
incomplete. Also several things are hidden from the docs. Thus, clean it
up and make it easier to read the rendered html docs.

Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <lossin@kernel.org>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://patch.msgid.link/20250811-lock-class-key-cleanup-v3-2-b12967ee1ca2@google.com

authored by

Alice Ryhl and committed by
Boqun Feng
106ab474 86f4a271

+40 -14
+40 -14
rust/kernel/sync.rs
··· 32 32 pub use refcount::Refcount; 33 33 pub use set_once::SetOnce; 34 34 35 - /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`. 35 + /// Represents a lockdep class. 36 + /// 37 + /// Wraps the kernel's `struct lock_class_key`. 36 38 #[repr(transparent)] 37 39 #[pin_data(PinnedDrop)] 38 40 pub struct LockClassKey { 39 41 #[pin] 40 42 inner: Opaque<bindings::lock_class_key>, 41 43 } 44 + 45 + // SAFETY: Unregistering a lock class key from a different thread than where it was registered is 46 + // allowed. 47 + unsafe impl Send for LockClassKey {} 42 48 43 49 // SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and 44 50 // provides its own synchronization. ··· 53 47 impl LockClassKey { 54 48 /// Initializes a statically allocated lock class key. 55 49 /// 56 - /// This is usually used indirectly through the [`static_lock_class!`] macro. 50 + /// This is usually used indirectly through the [`static_lock_class!`] macro. See its 51 + /// documentation for more information. 57 52 /// 58 53 /// # Safety 59 54 /// 60 55 /// * Before using the returned value, it must be pinned in a static memory location. 61 56 /// * The destructor must never run on the returned `LockClassKey`. 62 - #[doc(hidden)] 63 57 pub const unsafe fn new_static() -> Self { 64 58 LockClassKey { 65 59 inner: Opaque::uninit(), 66 60 } 67 61 } 68 62 69 - /// Initializes a dynamically allocated lock class key. In the common case of using a 70 - /// statically allocated lock class key, the static_lock_class! macro should be used instead. 63 + /// Initializes a dynamically allocated lock class key. 64 + /// 65 + /// In the common case of using a statically allocated lock class key, the 66 + /// [`static_lock_class!`] macro should be used instead. 71 67 /// 72 68 /// # Examples 69 + /// 73 70 /// ``` 74 - /// # use kernel::alloc::KBox; 75 - /// # use kernel::types::ForeignOwnable; 76 - /// # use kernel::sync::{LockClassKey, SpinLock}; 77 - /// # use pin_init::stack_pin_init; 71 + /// use kernel::alloc::KBox; 72 + /// use kernel::types::ForeignOwnable; 73 + /// use kernel::sync::{LockClassKey, SpinLock}; 74 + /// use pin_init::stack_pin_init; 78 75 /// 79 76 /// let key = KBox::pin_init(LockClassKey::new_dynamic(), GFP_KERNEL)?; 80 77 /// let key_ptr = key.into_foreign(); ··· 95 86 /// // SAFETY: We dropped `num`, the only use of the key, so the result of the previous 96 87 /// // `borrow` has also been dropped. Thus, it's safe to use from_foreign. 97 88 /// unsafe { drop(<Pin<KBox<LockClassKey>> as ForeignOwnable>::from_foreign(key_ptr)) }; 98 - /// 99 89 /// # Ok::<(), Error>(()) 100 90 /// ``` 101 91 pub fn new_dynamic() -> impl PinInit<Self> { ··· 104 96 }) 105 97 } 106 98 107 - pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key { 99 + /// Returns a raw pointer to the inner C struct. 100 + /// 101 + /// It is up to the caller to use the raw pointer correctly. 102 + pub fn as_ptr(&self) -> *mut bindings::lock_class_key { 108 103 self.inner.get() 109 104 } 110 105 } ··· 115 104 #[pinned_drop] 116 105 impl PinnedDrop for LockClassKey { 117 106 fn drop(self: Pin<&mut Self>) { 118 - // SAFETY: self.as_ptr was registered with lockdep and self is pinned, so the address 119 - // hasn't changed. Thus, it's safe to pass to unregister. 107 + // SAFETY: `self.as_ptr()` was registered with lockdep and `self` is pinned, so the address 108 + // hasn't changed. Thus, it's safe to pass it to unregister. 120 109 unsafe { bindings::lockdep_unregister_key(self.as_ptr()) } 121 110 } 122 111 } 123 112 124 113 /// Defines a new static lock class and returns a pointer to it. 125 - #[doc(hidden)] 114 + /// 115 + /// # Examples 116 + /// 117 + /// ``` 118 + /// use kernel::c_str; 119 + /// use kernel::sync::{static_lock_class, Arc, SpinLock}; 120 + /// 121 + /// fn new_locked_int() -> Result<Arc<SpinLock<u32>>> { 122 + /// Arc::pin_init(SpinLock::new( 123 + /// 42, 124 + /// c_str!("new_locked_int"), 125 + /// static_lock_class!(), 126 + /// ), GFP_KERNEL) 127 + /// } 128 + /// ``` 126 129 #[macro_export] 127 130 macro_rules! static_lock_class { 128 131 () => {{ ··· 147 122 $crate::prelude::Pin::static_ref(&CLASS) 148 123 }}; 149 124 } 125 + pub use static_lock_class; 150 126 151 127 /// Returns the given string, if one is provided, otherwise generates one based on the source code 152 128 /// location.