Commit e8fa0481 authored by Miguel Ojeda's avatar Miguel Ojeda
Browse files

Merge tag 'pin-init-v6.17' of https://github.com/Rust-for-Linux/linux into rust-next



Pull pin-init updates from Benno Lossin:
 "Added:

   - 'impl<T, E> [Pin]Init<T, E> for Result<T, E>', so results are now
     (pin-)initializers.

   - 'Zeroable::init_zeroed()' delegating to 'init_zeroed()'.

   - New 'zeroed()', a safe version of 'mem::zeroed()' and also provide
     it via 'Zeroable::zeroed()'.

   - Implement 'Zeroable' for 'Option<&T>' and 'Option<&mut T>'.

   - Implement 'Zeroable' for 'Option<[unsafe] [extern "abi"]
     fn(...args...) -> ret>' for '"Rust"' and '"C"' ABIs and up to 20
     arguments.

  Changed:

   - Blanket impls of 'Init' and 'PinInit' from 'impl<T, E>
     [Pin]Init<T, E> for T' to 'impl<T> [Pin]Init<T> for T'.

   - Renamed 'zeroed()' to 'init_zeroed()'.

  Upstream dev news:

   - More CI improvements to deny warnings, use '--all-targets'. Also
     check the synchronization status of the two '-next' branches in
     upstream and the kernel."

Acked-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>

* tag 'pin-init-v6.17' of https://github.com/Rust-for-Linux/linux:
  rust: pin-init: examples, tests: use `ignore` instead of conditionally compiling tests
  rust: init: remove doctest's `Error::from_errno` workaround
  rust: init: re-enable doctests
  rust: pin-init: implement `ZeroableOption` for function pointers with up to 20 arguments
  rust: pin-init: change `impl Zeroable for Option<NonNull<T>>` to `ZeroableOption for NonNull<T>`
  rust: pin-init: implement `ZeroableOption` for `&T` and `&mut T`
  rust: pin-init: add `zeroed()` & `Zeroable::zeroed()` functions
  rust: pin-init: add `Zeroable::init_zeroed`
  rust: pin-init: rename `zeroed` to `init_zeroed`
  rust: pin-init: feature-gate the `stack_init_reuse` test on the `std` feature
  rust: pin-init: examples: pthread_mutex: disable the main test for miri
  rust: pin-init: examples, tests: add conditional compilation in order to compile under any feature combination
  rust: pin-init: change blanket impls for `[Pin]Init` and add one for `Result<T, E>`
  rust: pin-init: improve safety documentation for `impl<T> [Pin]Init<T> for T`
parents 2009a2d5 fc3870dc
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
use crate::{
    bindings,
    block::mq::{operations::OperationsVTable, request::RequestDataWrapper, Operations},
    error,
    error::{self, Result},
    prelude::try_pin_init,
    types::Opaque,
};
@@ -41,7 +41,7 @@ pub fn new(
        // SAFETY: `blk_mq_tag_set` only contains integers and pointers, which
        // all are allowed to be 0.
        let tag_set: bindings::blk_mq_tag_set = unsafe { core::mem::zeroed() };
        let tag_set = core::mem::size_of::<RequestDataWrapper>()
        let tag_set: Result<_> = core::mem::size_of::<RequestDataWrapper>()
            .try_into()
            .map(|cmd_size| {
                bindings::blk_mq_tag_set {
@@ -56,12 +56,14 @@ pub fn new(
                    nr_maps: num_maps,
                    ..tag_set
                }
            });
            })
            .map(Opaque::new)
            .map_err(|e| e.into());

        try_pin_init!(TagSet {
            inner <- PinInit::<_, error::Error>::pin_chain(Opaque::new(tag_set?), |tag_set| {
            inner <- tag_set.pin_chain(|tag_set| {
                // SAFETY: we do not move out of `tag_set`.
                let tag_set = unsafe { Pin::get_unchecked_mut(tag_set) };
                let tag_set: &mut Opaque<_> = unsafe { Pin::get_unchecked_mut(tag_set) };
                // SAFETY: `tag_set` is a reference to an initialized `blk_mq_tag_set`.
                error::to_result( unsafe { bindings::blk_mq_alloc_tag_set(tag_set.get())})
            }),
+2 −2
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ pub fn new(
        data: impl PinInit<Data, Error>,
    ) -> impl PinInit<Self, Error> {
        try_pin_init!(Self {
            subsystem <- pin_init::zeroed().chain(
            subsystem <- pin_init::init_zeroed().chain(
                |place: &mut Opaque<bindings::configfs_subsystem>| {
                    // SAFETY: We initialized the required fields of `place.group` above.
                    unsafe {
@@ -261,7 +261,7 @@ pub fn new(
        data: impl PinInit<Data, Error>,
    ) -> impl PinInit<Self, Error> {
        try_pin_init!(Self {
            group <- pin_init::zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
            group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
                let place = v.get();
                let name = name.as_bytes_with_nul().as_ptr();
                // SAFETY: It is safe to initialize a group once it has been zeroed.
+10 −18
Original line number Diff line number Diff line
@@ -29,15 +29,15 @@
//!
//! ## General Examples
//!
//! ```rust,ignore
//! # #![allow(clippy::disallowed_names)]
//! ```rust
//! # #![expect(clippy::disallowed_names, clippy::undocumented_unsafe_blocks)]
//! use kernel::types::Opaque;
//! use pin_init::pin_init_from_closure;
//!
//! // assume we have some `raw_foo` type in C:
//! #[repr(C)]
//! struct RawFoo([u8; 16]);
//! extern {
//! extern "C" {
//!     fn init_foo(_: *mut RawFoo);
//! }
//!
@@ -66,25 +66,17 @@
//! });
//! ```
//!
//! ```rust,ignore
//! # #![allow(unreachable_pub, clippy::disallowed_names)]
//! ```rust
//! # #![expect(unreachable_pub, clippy::disallowed_names)]
//! use kernel::{prelude::*, types::Opaque};
//! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};
//! # mod bindings {
//! #     #![allow(non_camel_case_types)]
//! #     #![expect(non_camel_case_types, clippy::missing_safety_doc)]
//! #     pub struct foo;
//! #     pub unsafe fn init_foo(_ptr: *mut foo) {}
//! #     pub unsafe fn destroy_foo(_ptr: *mut foo) {}
//! #     pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }
//! # }
//! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
//! # trait FromErrno {
//! #     fn from_errno(errno: core::ffi::c_int) -> Error {
//! #         // Dummy error that can be constructed outside the `kernel` crate.
//! #         Error::from(core::fmt::Error)
//! #     }
//! # }
//! # impl FromErrno for Error {}
//! /// # Invariants
//! ///
//! /// `foo` is always initialized
@@ -206,7 +198,7 @@ fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
///
/// ```rust
/// use kernel::error::Error;
/// use pin_init::zeroed;
/// use pin_init::init_zeroed;
/// struct BigBuf {
///     big: KBox<[u8; 1024 * 1024 * 1024]>,
///     small: [u8; 1024 * 1024],
@@ -215,7 +207,7 @@ fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
/// impl BigBuf {
///     fn new() -> impl Init<Self, Error> {
///         try_init!(Self {
///             big: KBox::init(zeroed(), GFP_KERNEL)?,
///             big: KBox::init(init_zeroed(), GFP_KERNEL)?,
///             small: [0; 1024 * 1024],
///         }? Error)
///     }
@@ -264,7 +256,7 @@ macro_rules! try_init {
/// ```rust
/// # #![feature(new_uninit)]
/// use kernel::error::Error;
/// use pin_init::zeroed;
/// use pin_init::init_zeroed;
/// #[pin_data]
/// struct BigBuf {
///     big: KBox<[u8; 1024 * 1024 * 1024]>,
@@ -275,7 +267,7 @@ macro_rules! try_init {
/// impl BigBuf {
///     fn new() -> impl PinInit<Self, Error> {
///         try_pin_init!(Self {
///             big: KBox::init(zeroed(), GFP_KERNEL)?,
///             big: KBox::init(init_zeroed(), GFP_KERNEL)?,
///             small: [0; 1024 * 1024],
///             ptr: core::ptr::null_mut(),
///         }? Error)
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ impl DriverData {
    fn new() -> impl PinInit<Self, Error> {
        try_pin_init!(Self {
            status <- CMutex::new(0),
            buffer: Box::init(pin_init::zeroed())?,
            buffer: Box::init(pin_init::init_zeroed())?,
        }? Error)
    }
}
+16 −12
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

// Struct with size over 1GiB
#[derive(Debug)]
#[allow(dead_code)]
pub struct BigStruct {
    buf: [u8; 1024 * 1024 * 1024],
    a: u64,
@@ -20,14 +21,16 @@ pub struct ManagedBuf {

impl ManagedBuf {
    pub fn new() -> impl Init<Self> {
        init!(ManagedBuf { buf <- zeroed() })
        init!(ManagedBuf { buf <- init_zeroed() })
    }
}

fn main() {
    #[cfg(any(feature = "std", feature = "alloc"))]
    {
        // we want to initialize the struct in-place, otherwise we would get a stackoverflow
        let buf: Box<BigStruct> = Box::init(init!(BigStruct {
        buf <- zeroed(),
            buf <- init_zeroed(),
            a: 7,
            b: 186,
            c: 7789,
@@ -37,3 +40,4 @@ fn main() {
        .unwrap();
        println!("{}", core::mem::size_of_val(&*buf));
    }
}
Loading