From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id BFD90C3DA4A for ; Wed, 14 Aug 2024 08:26:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3744B6B0092; Wed, 14 Aug 2024 04:26:29 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 324AE6B0093; Wed, 14 Aug 2024 04:26:29 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 1C6136B0095; Wed, 14 Aug 2024 04:26:29 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id F2EF06B0092 for ; Wed, 14 Aug 2024 04:26:28 -0400 (EDT) Received: from smtpin14.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 81CD51A0D05 for ; Wed, 14 Aug 2024 08:26:28 +0000 (UTC) X-FDA: 82450169256.14.DE999CF Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by imf03.hostedemail.com (Postfix) with ESMTP id 2A57120004 for ; Wed, 14 Aug 2024 08:26:24 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=P6Q1DpqD; spf=pass (imf03.hostedemail.com: domain of aliceryhl@google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=aliceryhl@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1723623913; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=+0MBDb5+vXEVzKIZLapFfRuEtH5IYfsSmO/Hh3Pyjq4=; b=YxgMF1jQtS4+FVYtFFxI2e0ASG97jeiFFuONdJC6MtHlJZtBXxZ3KtdOlCa9kOE1dRvjM7 m7N2DhOZJv8c5W18dHBIzXMz3/iqvORpmzd4+6HRUZgjJa1dsHd8UxivHiwhviY6AUkfbk AxYCsgedzJZ9G2p1ggAJqmirAvldFcQ= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1723623913; a=rsa-sha256; cv=none; b=EdBBpMYra3DRM7PNveHTnCTs0jGcjFhc3yXfmsoZwOW2OYX2D6vmt093NXdZysElr/c1qC 1ifM3DCAKYXB8z1K7g9ZbBPagLQRVX+Kohp6d76Zjpy0A2nLQnKjzgqzQ1K1LsUzHsMhrS WJ8vF6sktqonKtEOe+jrkXc6VvnFmRA= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=P6Q1DpqD; spf=pass (imf03.hostedemail.com: domain of aliceryhl@google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=aliceryhl@google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-3687fd09251so3509721f8f.0 for ; Wed, 14 Aug 2024 01:26:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723623983; x=1724228783; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=+0MBDb5+vXEVzKIZLapFfRuEtH5IYfsSmO/Hh3Pyjq4=; b=P6Q1DpqDIsk5O94Iu5FWJljs2z/gDC11Vp3UdF1JX69R8KtI+5Iviw7fL6C4OhHKTF 9jDeDfcpbZI5kAZp5qxwb+q864MjiXA/+1rTvltLd9/PVzNmlaoYWKJ2Xq42po63uudp x2IQ8VUMSQTjJU5K4NZP55xZKHCDwXrq/83MMUEy5PdRrK68lbe4BpSbjFnsJ5pa3ztH xE8+hb/h3hTKMEJNSrJ//jHAxujzpQJHiHj7La9GNxw1K6pycfMoWDomQSStIIJsjJ3W fkDWolYPp/YI9zyHJ1BtLXFSiGwAOtzSfBnIC0fELZF2ahtkhZJdNXo+IsEwfM0XdVPI Dljg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723623983; x=1724228783; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+0MBDb5+vXEVzKIZLapFfRuEtH5IYfsSmO/Hh3Pyjq4=; b=nyv8rLXfNVbmw59oyLdy2D1kduup+imNk60I7hNfxBr0tXXqMoUnmdQRLiLX4t0bbX yNi+zcqS+JHRZCLo4LHUbJ/a6cEtlF+QUW8vpFMjBB+ejIzIvSrPhmhxCWc7yZT0YNEK 9zr7eYzW0iLSQJ9k+lyoJSMVbq848IgFFoRcfkFut54u89q0FslrldemptxCGW492QdL FEpoknJ8MXoC3/HhQSi1uY1+X7HrmX7FnmuNpm66paQ3VkrsLQBeoL+18nuXwINpLYhm OtC0z1X1dtKvgLRP9OwxZrbwBvTZZHefOiRas6ZV41XvBKFM8Ww0MoTViKZukGLGUe7S Asiw== X-Forwarded-Encrypted: i=1; AJvYcCV84oy+fUK4NaCqEH7m+jUa1QJjWHurITBlpwj60YWHMxmWIYw81zOhTTMIl4FotlBg/vC2Sqq55sLAdZJxM60jLTI= X-Gm-Message-State: AOJu0YwELVZ/T1/TP9m0QysLGnBlD7SHxb/9wEHourBS8huxFsEWtbe2 KNt+S33FedAIRnDn53LD9SEd4NQU3s+bJFhN7tHOtT/vDpNXb4brLXIOzqi0EH7jBCT77KrdIJL ky5HbaIDQkb0MZnxaLRsd6LEKqBABZC1fuB79 X-Google-Smtp-Source: AGHT+IHCm0scg6mxW0JEpekgZhvKx5QWQ3ad6jquJgs9Up2YmI7n5FfGy3MiFPjp1CZznyAwqTEgCkSzOHAEpNW6ylk= X-Received: by 2002:a5d:5e13:0:b0:371:79f0:2cf6 with SMTP id ffacd0b85a97d-37179f02ef3mr583706f8f.11.1723623983239; Wed, 14 Aug 2024 01:26:23 -0700 (PDT) MIME-Version: 1.0 References: <20240812182355.11641-1-dakr@kernel.org> <20240812182355.11641-10-dakr@kernel.org> In-Reply-To: <20240812182355.11641-10-dakr@kernel.org> From: Alice Ryhl Date: Wed, 14 Aug 2024 10:26:10 +0200 Message-ID: Subject: Re: [PATCH v5 09/26] rust: alloc: implement kernel `Box` To: Danilo Krummrich Cc: ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, benno.lossin@proton.me, a.hindborg@samsung.com, akpm@linux-foundation.org, daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, cjia@nvidia.com, jhubbard@nvidia.com, airlied@redhat.com, ajanulgu@redhat.com, lyude@redhat.com, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Stat-Signature: wkp1jf3si3swzi7z55a5oaj7irhrb8n8 X-Rspamd-Queue-Id: 2A57120004 X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1723623984-204622 X-HE-Meta: U2FsdGVkX1+idV9tbIbwnMkaTR18XUQjGbGusDhn+fWDfzOh2V0tql3Qcfv3vtSwO/v6T6jqhVWOuJ2fqcaI2UadMBlOAafyBhvzA8KCvH8HNe7t2vTZ5AyCbZhxjy0CSGbmgkeRCNKP+prwQE3n1+6KEU182EuQ21Gupe0yrDeU+e9zqu4SP8pkPBVGUepkwSNZspQFjgxS510u1PshNEhxJx7ZYSfEC06c37bC0JiEV3Uo97jKyKI23/80OpczADwON9wjwru1XPDXQLe6JaM4j7FfkHb8P0k2evffVdCtvL0A2DZ7z9ux0ltHRgd6Y6Sk22hfo8v8WaZikbd3jRuD7W4LLjhmSqFyZ5e3P7gl1w/BqQz4W+M7G6+0KW4CrIiJmZxr03nwLe/wsn/vpbv1x6gGm8bLPJNUCDgzB9wV+7F6XfvQkKXP9lDvMFPF5eYFi3mnW3gk85vCcowMNQ1f3kJ3nIJ3kqp/hb5GH9RahQuVi37BrqScW2U/xvudJY+nyDKSNc953A7xQp1tA1+hfwJgXb5IsqVJAqIDe+VXZnhmUpWdtNSFxgf2W0kpE6DtcVJPv0/uqBx037chYz7KONdBhpM1zGvyulU/t1oCEPBE0Xa3JA/ZJWAXVhNz3YWhrCS88rgtfCvml3VGqNDhyAukyBT2acZgXD/SC+zAn+tudIeB8NSKDXmNPcYv9lRNe1OFR/h70GdtSFpfkjBP+CXOm7k6SLMdNvRPgJIB0isf4RyH7Q52OX/oWP7tj+4rPhmn5fP9FfHD9hFenspZoqVt2RPKU2qa925ZJx+pVDZzLoGAgrhoiThXl8XG7LDfRX2sqYrz5FmlhE3uIvjqmRWnrS93nGh3H3Ph/3GnV+QFVQlsimuv/qrkn+fdzO5lmQxO7RzSJg4feortpsAJRL6Gz5XWa4+TmwYiz0gFk8NnLdY/uzlWHk5ooiFmgFk3IGNhNFHKq9W75J2 MtyKq9MM v20/2Y/0PfWY4LdhQdsAd0imbFbyERyM/+tN7QdAilM5mFFktnVOFgeUJqDmGobKXs9Ol7ucBsIdh+qZ4ZY6s+CBhvXTbxlHHtjbhj7d/V+GsM1sdt8k9Fj/XHInc9oWw6H1OoyGN4O27RZU67SstrxNu0CNUPjl/D6AXxUZCBtY3UicC5gY0Q4HN9Yv+UkoIvGj377r2jwSqfDYGiV3DSkrnHV0cwceIWHLwTCVNGxykYzE3F/GtPXa+VpTxTZ67UcHUz5mPgXXxBL7I3uQNLcwEaJrCa16bP+0BOSFuelOlCJoeiCMurzIuxnfiWpdCvFlnkD7HyUjK6alpvynewzP2iJKgdyguDZ93rjC0V4y0YLQ4TvV6371/4FfkabiZ40cl X-Bogosity: Ham, tests=bogofilter, spamicity=0.000006, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: On Mon, Aug 12, 2024 at 8:25=E2=80=AFPM Danilo Krummrich = wrote: > > `Box` provides the simplest way to allocate memory for a generic type > with one of the kernel's allocators, e.g. `Kmalloc`, `Vmalloc` or > `KVmalloc`. > > In contrast to Rust's `Box` type, the kernel `Box` type considers the > kernel's GFP flags for all appropriate functions, always reports > allocation failures through `Result<_, AllocError>` and remains > independent from unstable features. > > Signed-off-by: Danilo Krummrich > --- > rust/kernel/alloc.rs | 6 + > rust/kernel/alloc/kbox.rs | 423 ++++++++++++++++++++++++++++++++++++++ > rust/kernel/prelude.rs | 2 +- > 3 files changed, 430 insertions(+), 1 deletion(-) > create mode 100644 rust/kernel/alloc/kbox.rs > > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs > index 295107777a12..ed46b69204d0 100644 > --- a/rust/kernel/alloc.rs > +++ b/rust/kernel/alloc.rs > @@ -5,6 +5,7 @@ > #[cfg(not(any(test, testlib)))] > pub mod allocator; > pub mod box_ext; > +pub mod kbox; > pub mod vec_ext; > > #[cfg(any(test, testlib))] > @@ -13,6 +14,11 @@ > #[cfg(any(test, testlib))] > pub use self::allocator_test as allocator; > > +pub use self::kbox::Box; > +pub use self::kbox::KBox; > +pub use self::kbox::KVBox; > +pub use self::kbox::VBox; > + > /// Indicates an allocation error. > #[derive(Copy, Clone, PartialEq, Eq, Debug)] > pub struct AllocError; > diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs > new file mode 100644 > index 000000000000..67bdfc0712d2 > --- /dev/null > +++ b/rust/kernel/alloc/kbox.rs > @@ -0,0 +1,423 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +//! Implementation of [`Box`]. > + > +use super::{AllocError, Allocator, Flags}; > +use core::fmt; > +use core::marker::PhantomData; > +use core::mem::ManuallyDrop; > +use core::mem::MaybeUninit; > +use core::ops::{Deref, DerefMut}; > +use core::pin::Pin; > +use core::ptr::NonNull; > +use core::result::Result; > + > +use crate::init::{InPlaceInit, Init, PinInit}; > +use crate::types::ForeignOwnable; > + > +/// The kernel's [`Box`] type - a heap allocation for a single value of = type `T`. > +/// > +/// This is the kernel's version of the Rust stdlib's `Box`. There are a= couple of differences, > +/// for example no `noalias` attribute is emitted and partially moving o= ut of a `Box` is not > +/// supported. > +/// > +/// `Box` works with any of the kernel's allocators, e.g. [`super::alloc= ator::Kmalloc`], > +/// [`super::allocator::Vmalloc`] or [`super::allocator::KVmalloc`]. The= re are aliases for `Box` > +/// with these allocators ([`KBox`], [`VBox`], [`KVBox`]). > +/// > +/// When dropping a [`Box`], the value is also dropped and the heap memo= ry is automatically freed. > +/// > +/// # Examples > +/// > +/// ``` > +/// let b =3D KBox::::new(24_u64, GFP_KERNEL)?; > +/// > +/// assert_eq!(*b, 24_u64); > +/// > +/// # Ok::<(), Error>(()) This is a minor nit, but when hiding lines in examples you should avoid having the rendered docs have empty lines at the beginning/end. There are also several examples of this below with the kernel::bindings import. > +/// ``` > +/// > +/// ``` > +/// # use kernel::bindings; > +/// > +/// const SIZE: usize =3D bindings::KMALLOC_MAX_SIZE as usize + 1; > +/// struct Huge([u8; SIZE]); > +/// > +/// assert!(KBox::::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()= ); > +/// ``` > +/// > +/// ``` > +/// # use kernel::bindings; > +/// > +/// const SIZE: usize =3D bindings::KMALLOC_MAX_SIZE as usize + 1; > +/// struct Huge([u8; SIZE]); > +/// > +/// assert!(KVBox::::new_uninit(GFP_KERNEL).is_ok()); > +/// ``` > +/// > +/// # Invariants > +/// > +/// The [`Box`]' pointer always properly aligned and either points to me= mory allocated with `A` or, > +/// for zero-sized types, is a dangling pointer. > +pub struct Box(NonNull, PhantomData); I was about to say this needs a PhantomData too, but I guess it isn't necessary anymore. https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-= drop-checking > +// SAFETY: `Box` is `Send` if `T` is `Send` because the data referenced = by `self.0` is unaliased. Instead of "unaliased" I would probably just say "because the Box owns a T"= . > + > +// SAFETY: `Box` is `Sync` if `T` is `Sync` because the data referenced = by `self.0` is unaliased. > +unsafe impl Sync for Box > +where > + T: Send + ?Sized, > + A: Allocator, This needs to say `T: Sync` instead of `T: Send`. That matches the std Box. > + > +impl Box > +where > + T: ?Sized, > + A: Allocator, > +{ > + /// Creates a new `Box` from a raw pointer. > + /// > + /// # Safety > + /// > + /// `raw` must point to valid memory, previously be allocated with `= A`, and provide at least > + /// the size of type `T`. For ZSTs `raw` must be a dangling pointer. Hmm. I don't love this wording. How about this? For non-ZSTs, `raw` must point at a live allocation allocated with `A` that is sufficiently aligned for and holds a valid `T`. The caller passes ownership of the allocation to the `Box`. For ZSTs, the pointer must be non-null and aligned. > +impl From> for Pin> > +where > + T: ?Sized, > + A: Allocator, > +{ > + /// Converts a `Box` into a `Pin>`. If `T` does not = implement [`Unpin`], then > + /// `*b` will be pinned in memory and can't be moved. > + /// > + /// See [`Box::into_pin`] for more details. > + fn from(b: Box) -> Self { > + Box::into_pin(b) I still think it makes more sense to match std and only provide From and not an into_pin, but it's not a blocker. Alice