Skip to content

Commit 57db449

Browse files
authored
Merge pull request #95 from Rust-for-Linux/rust-document-all
Add missing docs, enforce `missing-docs` and doc `compiler_builtins`
2 parents 8a14ed6 + f971606 commit 57db449

19 files changed

+456
-149
lines changed

drivers/char/rust_example.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Rust example module
4+
35
#![no_std]
46
#![feature(allocator_api, global_asm)]
57
#![feature(test)]

rust/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,18 @@ quiet_cmd_rustdoc = RUSTDOC $<
1414
$(RUSTDOC) $(filter-out --emit=%, $(rustc_flags)) \
1515
$(rustdoc_target_flags) -L $(objtree)/rust/ \
1616
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
17-
-Wmissing-docs @$(objtree)/include/generated/rustc_cfg $<
17+
-Fmissing-docs @$(objtree)/include/generated/rustc_cfg $<
1818

19-
rustdoc: rustdoc-module rustdoc-kernel
19+
rustdoc: rustdoc-module rustdoc-compiler_builtins rustdoc-kernel
2020

2121
rustdoc-module: private rustdoc_target_flags = --crate-type proc-macro \
2222
--extern proc_macro
2323
rustdoc-module: $(srctree)/rust/module.rs FORCE
2424
$(call if_changed,rustdoc)
2525

26+
rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE
27+
$(call if_changed,rustdoc)
28+
2629
rustdoc-kernel: private rustdoc_target_flags = --extern alloc \
2730
--extern module=$(objtree)/rust/libmodule.so
2831
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-module \

rust/compiler_builtins.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3-
//! Our `compiler_builtins`.
3+
//! Our own `compiler_builtins`.
44
//!
5-
//! Rust provides `compiler_builtins` as a port of LLVM's `compiler-rt`.
6-
//! Since we don't need the vast majority of them, we avoid the dependency
5+
//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
6+
//! Since we do not need the vast majority of them, we avoid the dependency
77
//! by providing this file.
88
//!
9-
//! At the moment, some builtins are required that shouldn't be. For instance,
10-
//! `core` has floating-point functionality which we shouldn't be compiling in.
11-
//! For the moment, we define them to `panic!` at runtime for simplicity.
9+
//! At the moment, some builtins are required that should not be. For instance,
10+
//! [`core`] has floating-point functionality which we should not be compiling
11+
//! in. For the moment, we define them to [`panic!`] at runtime for simplicity.
1212
//! These are actually a superset of the ones we actually need to define,
1313
//! but it seems simpler to ban entire categories at once. In the future,
14-
//! we might be able to remove all this by providing our own custom `core` etc.,
15-
//! or perhaps `core` itself might provide `cfg` options to disable enough
16-
//! functionality to avoid requiring some of these.
14+
//! we might be able to remove all this by providing our own custom [`core`]
15+
//! etc., or perhaps [`core`] itself might provide `cfg` options to disable
16+
//! enough functionality to avoid requiring some of these.
1717
//!
18-
//! In any case, all these symbols are weakened to ensure we don't override
18+
//! In any case, all these symbols are weakened to ensure we do not override
1919
//! those that may be provided by the rest of the kernel.
20+
//!
21+
//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
22+
//! [`compiler-rt`]: https://compiler-rt.llvm.org/
2023
2124
#![feature(compiler_builtins)]
2225
#![compiler_builtins]
@@ -26,6 +29,7 @@
2629
macro_rules! define_panicking_intrinsics(
2730
($reason: tt, { $($ident: ident, )* }) => {
2831
$(
32+
#[doc(hidden)]
2933
#[no_mangle]
3034
pub extern "C" fn $ident() {
3135
panic!($reason);

rust/kernel/allocator.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Allocator support.
4+
35
use core::alloc::{GlobalAlloc, Layout};
46
use core::ptr;
57

@@ -10,8 +12,8 @@ pub struct KernelAllocator;
1012

1113
unsafe impl GlobalAlloc for KernelAllocator {
1214
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
13-
// krealloc is used instead of kmalloc because kmalloc is an inline function and can't be
14-
// bound to as a result
15+
// `krealloc()` is used instead of `kmalloc()` because the latter is
16+
// an inline function and cannot be bound to as a result.
1517
bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8
1618
}
1719

rust/kernel/bindings.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Bindings
4+
//!
5+
//! Imports the generated bindings by `bindgen`.
6+
37
#[allow(
48
clippy::all,
59
non_camel_case_types,

rust/kernel/bindings_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
#include <linux/version.h>
1111
#include <linux/miscdevice.h>
1212

13-
// bindgen gets confused at certain things
13+
// `bindgen` gets confused at certain things
1414
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
1515
const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;

rust/kernel/c_types.rs

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,128 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! C types for the bindings.
4+
//!
5+
//! The bindings generated by `bindgen` use these types to map to the C ones.
6+
//!
7+
//! C's standard integer types may differ in width depending on
8+
//! the architecture, thus we need to conditionally compile those.
9+
310
#![allow(non_camel_case_types)]
411

512
#[cfg(any(target_arch = "arm", target_arch = "x86"))]
613
mod c {
14+
/// C `void` type.
715
pub type c_void = core::ffi::c_void;
816

17+
/// C `char` type.
918
pub type c_char = i8;
19+
20+
/// C `signed char` type.
1021
pub type c_schar = i8;
22+
23+
/// C `unsigned char` type.
1124
pub type c_uchar = u8;
1225

26+
/// C `short` type.
1327
pub type c_short = i16;
28+
29+
/// C `unsigned short` type.
1430
pub type c_ushort = u16;
1531

32+
/// C `int` type.
1633
pub type c_int = i32;
34+
35+
/// C `unsigned int` type.
1736
pub type c_uint = u32;
1837

38+
/// C `long` type.
1939
pub type c_long = i32;
40+
41+
/// C `unsigned long` type.
2042
pub type c_ulong = u32;
2143

44+
/// C `long long` type.
2245
pub type c_longlong = i64;
46+
47+
/// C `unsigned long long` type.
2348
pub type c_ulonglong = u64;
2449

50+
/// C `ssize_t` type (typically defined in `<sys/types.h>` by POSIX).
51+
///
52+
/// For some 32-bit architectures like this one, the kernel defines it as
53+
/// `int`, i.e. it is an [`i32`].
2554
pub type c_ssize_t = isize;
55+
56+
/// C `size_t` type (typically defined in `<stddef.h>`).
57+
///
58+
/// For some 32-bit architectures like this one, the kernel defines it as
59+
/// `unsigned int`, i.e. it is an [`u32`].
2660
pub type c_size_t = usize;
2761
}
2862

2963
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
3064
mod c {
65+
/// C `void` type.
3166
pub type c_void = core::ffi::c_void;
3267

68+
/// C `char` type.
3369
pub type c_char = i8;
70+
71+
/// C `signed char` type.
3472
pub type c_schar = i8;
73+
74+
/// C `unsigned char` type.
3575
pub type c_uchar = u8;
3676

77+
/// C `short` type.
3778
pub type c_short = i16;
79+
80+
/// C `unsigned short` type.
3881
pub type c_ushort = u16;
3982

83+
/// C `int` type.
4084
pub type c_int = i32;
85+
86+
/// C `unsigned int` type.
4187
pub type c_uint = u32;
4288

89+
/// C `long` type.
4390
pub type c_long = i64;
91+
92+
/// C `unsigned long` type.
4493
pub type c_ulong = u64;
4594

95+
/// C `long long` type.
4696
pub type c_longlong = i64;
97+
98+
/// C `unsigned long long` type.
4799
pub type c_ulonglong = u64;
48100

101+
/// C `ssize_t` type (typically defined in `<sys/types.h>` by POSIX).
102+
///
103+
/// For 64-bit architectures like this one, the kernel defines it as
104+
/// `long`, i.e. it is an [`i64`].
49105
pub type c_ssize_t = isize;
106+
107+
/// C `size_t` type (typically defined in `<stddef.h>`).
108+
///
109+
/// For 64-bit architectures like this one, the kernel defines it as
110+
/// `unsigned long`, i.e. it is an [`u64`].
50111
pub type c_size_t = usize;
51112
}
52113

53114
pub use c::*;
54115

55-
/// Reads string until null byte is reached and returns slice excluding the terminating null.
116+
/// Reads string until null byte is reached and returns slice excluding the
117+
/// terminating null.
56118
///
57119
/// # Safety
58120
///
59121
/// The data from the pointer until the null terminator must be valid for reads
60122
/// and not mutated for all of `'a`. The length of the string must also be less
61-
/// than `isize::MAX`. See the documentation on [`from_raw_parts`] for further
62-
/// details on safety of converting a pointer to a slice.
63-
///
64-
/// [`from_raw_parts`]: https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html
123+
/// than `isize::MAX`. See the documentation on
124+
/// [`core::slice::from_raw_parts()`] for further details on safety of
125+
/// converting a pointer to a slice.
65126
pub unsafe fn c_string_bytes<'a>(ptr: *const crate::c_types::c_char) -> &'a [u8] {
66127
let length = crate::bindings::strlen(ptr) as usize;
67128
&core::slice::from_raw_parts(ptr as *const u8, length)

rust/kernel/chrdev.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Character devices.
4+
//!
5+
//! Also called "char devices", `chrdev`, `cdev`.
6+
//!
7+
//! C header: [`include/linux/cdev.h`](../../../../include/linux/cdev.h)
8+
//!
9+
//! Reference: <https://www.kernel.org/doc/html/latest/core-api/kernel-api.html#char-devices>
10+
311
use alloc::boxed::Box;
412
use core::convert::TryInto;
513
use core::marker::PhantomPinned;
@@ -19,8 +27,9 @@ struct RegistrationInner<const N: usize> {
1927
_pin: PhantomPinned,
2028
}
2129

22-
/// chrdev registration. May contain up to a fixed number (`N`) of devices.
23-
/// Must be pinned.
30+
/// Character device registration.
31+
///
32+
/// May contain up to a fixed number (`N`) of devices. Must be pinned.
2433
pub struct Registration<const N: usize> {
2534
name: CStr<'static>,
2635
minors_start: u16,
@@ -29,6 +38,15 @@ pub struct Registration<const N: usize> {
2938
}
3039

3140
impl<const N: usize> Registration<{ N }> {
41+
/// Creates a [`Registration`] object for a character device.
42+
///
43+
/// This does *not* register the device: see [`Self::register()`].
44+
///
45+
/// This associated function is intended to be used when you need to avoid
46+
/// a memory allocation, e.g. when the [`Registration`] is a member of
47+
/// a bigger structure inside your [`crate::KernelModule`] instance. If you
48+
/// are going to pin the registration right away, call
49+
/// [`Self::new_pinned()`] instead.
3250
pub fn new(
3351
name: CStr<'static>,
3452
minors_start: u16,
@@ -42,6 +60,9 @@ impl<const N: usize> Registration<{ N }> {
4260
}
4361
}
4462

63+
/// Creates a pinned [`Registration`] object for a character device.
64+
///
65+
/// This does *not* register the device: see [`Self::register()`].
4566
pub fn new_pinned(
4667
name: CStr<'static>,
4768
minors_start: u16,
@@ -53,15 +74,17 @@ impl<const N: usize> Registration<{ N }> {
5374
this_module,
5475
))?))
5576
}
56-
/// Register a character device with this range. Call this once per device
57-
/// type (up to `N` times).
77+
78+
/// Registers a character device.
79+
///
80+
/// You may call this once per device type, up to `N` times.
5881
pub fn register<T: file_operations::FileOperations>(self: Pin<&mut Self>) -> KernelResult<()> {
59-
// SAFETY: we must ensure that we never move out of `this`.
82+
// SAFETY: We must ensure that we never move out of `this`.
6083
let this = unsafe { self.get_unchecked_mut() };
6184
if this.inner.is_none() {
6285
let mut dev: bindings::dev_t = 0;
63-
// SAFETY: Calling unsafe function. `this.name` has 'static
64-
// lifetime
86+
// SAFETY: Calling unsafe function. `this.name` has `'static`
87+
// lifetime.
6588
let res = unsafe {
6689
bindings::alloc_chrdev_region(
6790
&mut dev,
@@ -86,7 +109,8 @@ impl<const N: usize> Registration<{ N }> {
86109
return Err(Error::EINVAL);
87110
}
88111
let cdev = inner.cdevs[inner.used].as_mut_ptr();
89-
// SAFETY: calling unsafe functions and manipulating MaybeUninit ptr.
112+
// SAFETY: Calling unsafe functions and manipulating `MaybeUninit`
113+
// pointer.
90114
unsafe {
91115
bindings::cdev_init(cdev, &file_operations::FileOperationsVtable::<T>::VTABLE);
92116
(*cdev).owner = this.this_module.0;
@@ -100,14 +124,14 @@ impl<const N: usize> Registration<{ N }> {
100124
}
101125
}
102126

103-
// SAFETY: `Registration` doesn't expose any of its state across threads (it's
104-
// fine for multiple threads to have a shared reference to it).
127+
// SAFETY: `Registration` does not expose any of its state across threads
128+
// (it is fine for multiple threads to have a shared reference to it).
105129
unsafe impl<const N: usize> Sync for Registration<{ N }> {}
106130

107131
impl<const N: usize> Drop for Registration<{ N }> {
108132
fn drop(&mut self) {
109133
if let Some(inner) = self.inner.as_mut() {
110-
// SAFETY: calling unsafe functions, `0..inner.used` of
134+
// SAFETY: Calling unsafe functions, `0..inner.used` of
111135
// `inner.cdevs` are initialized in `Registration::register`.
112136
unsafe {
113137
for i in 0..inner.used {

0 commit comments

Comments
 (0)