From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE4731B3F2C for ; Thu, 4 Jul 2024 17:08:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112903; cv=none; b=gRQBlWuYY4hFfAUn3tzewJHFuzgKvHZj6s2kRPRXSK4kxmqT4tofDUWGu4th+RZoZSKnMaVDoqu+XbYbjUeHX6hiQhd7lfJM93EcweUY+pC4G7pUOVG/tKB+FqambUno3FhqiO41VKjvIfEkUQZ+OT1ySe33wuQzv7rPqBqF3b0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112903; c=relaxed/simple; bh=3XWf+tqZEw33+PZlZUtYxgrm0fV1xVHRbQpdrge2Weo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MLWYF5BEClOkF3U5/d7ek/abZdDQW7dVGifkP65z66rSmdiyhN+3HdHfaaMdU4gFXgchLYvFWjA9C1YNt5y56yCqn1U8V3i3HX31w3ffmyPlFsMbwJut4nF4GBid2Sizz/XwaINPepHNS/E7qzWcv7Cy8SQLqoejPDfmYf4X/bo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=cGTjUIa1; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="cGTjUIa1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vphM9iJmRWkBamFnV9XKqsHbOU4Zx/cdWYFfn2wn3+4=; b=cGTjUIa1Tk+lPwkozfYXakMmBEaNzxaeN3ZrYbNHbUUIMXphsDmFLhUzXdYQV+cE5HC/8k FAbrKUGp1Phnad7BN0r70f8NnOSN87B+0K1nakolDXX81LG4JUH5aouezWlcAZZ3rpKlcd MHetQt5+9AVW09O6uAI4EX0KW3VizfM= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-528-XXd29k67O9SlSXLNSMqoFQ-1; Thu, 04 Jul 2024 13:08:19 -0400 X-MC-Unique: XXd29k67O9SlSXLNSMqoFQ-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-367879e8395so457425f8f.0 for ; Thu, 04 Jul 2024 10:08:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112898; x=1720717698; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vphM9iJmRWkBamFnV9XKqsHbOU4Zx/cdWYFfn2wn3+4=; b=SeF4ln4xrq2kHzFqT24BOZDdivVfMxsCycZPAT5pY62iQurz3yc3b84dCW6IyVhomw Dl0X+dBSUgtY6lzU1vrCD6fKBrZHbJud29FJXSNfNsFxjZIlmSS1qrwFGBWqcbYYBFCx ilmIlwawtG0ER3b6vRih5sqqnG2bBIxPO4jcRm+fOy3C8LJAbs2e9gyFLVoWDO5ed50X 0YKzHqY9Tsj9U/tSu15ajmFcs7JxkvLTWqXzePEXG+WOSoqU87Vg6ebnOVIAcp3Pt8OL Uas0rEUtrQ9ySY2byO5d0x3iLxCFp1n0PfhFasmujoVcAyVCQ6jgVzKJedLaQMFicy1u h7tw== X-Forwarded-Encrypted: i=1; AJvYcCWg6mWOkdnIViCCAOKmnB+UyqZixvsEn5Ljxut+f24eJGtgA7VI4x1jZOMn/w0lXudlqaTz32mOw1qI6CqJH+7ONXbtg78R1Yi6G1DV X-Gm-Message-State: AOJu0YybIzpuip1Nzo4Z0wLvHo3ym3fS7GF/aBFf3zgqz4MtT4zdABi8 ET9q2pmznnElLuMxg7/M0P3yWZod3HZj2W/CEPAbZPP+z1yV98YJASwxNVeivagfNGzTEH7+DA0 O8J/8IGQEwH6DWkvy1tqHVYKjUoLMtLBSgXx+LXLYjyEiMqwvlAbJDSdLPh5yKQ== X-Received: by 2002:adf:facf:0:b0:367:8fc3:a25b with SMTP id ffacd0b85a97d-3679dd31215mr1461496f8f.42.1720112898280; Thu, 04 Jul 2024 10:08:18 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFOQrlOgzUp2s25TyvjFOYtHEEXKGFugmXIqiA5JDYJbXkI5jgBcotLg9FeuRNMnsJcDHO7fA== X-Received: by 2002:adf:facf:0:b0:367:8fc3:a25b with SMTP id ffacd0b85a97d-3679dd31215mr1461481f8f.42.1720112897828; Thu, 04 Jul 2024 10:08:17 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367a1805e53sm1391438f8f.22.2024.07.04.10.08.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:17 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 01/20] rust: alloc: add `Allocator` trait Date: Thu, 4 Jul 2024 19:06:29 +0200 Message-ID: <20240704170738.3621-2-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a kernel specific `Allocator` trait, that in contrast to the one in Rust's core library doesn't require unstable features and supports GFP flags. Subsequent patches add the following trait implementors: `Kmalloc`, `Vmalloc` and `KVmalloc`. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 531b5e471cb1..462e00982510 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -11,6 +11,7 @@ /// Indicates an allocation error. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct AllocError; +use core::{alloc::Layout, ptr, ptr::NonNull}; =20 /// Flags to be used when allocating memory. /// @@ -71,3 +72,75 @@ pub mod flags { /// small allocations. pub const GFP_NOWAIT: Flags =3D Flags(bindings::GFP_NOWAIT); } + +/// The kernel's [`Allocator`] trait. +/// +/// An implementation of [`Allocator`] can allocate, re-allocate and free = memory buffer described +/// via [`Layout`]. +/// +/// [`Allocator`] is designed to be implemented on ZSTs; its safety requir= ements to not allow for +/// keeping a state throughout an instance. +/// +/// # Safety +/// +/// Memory returned from an allocator must point to a valid memory buffer = and remain valid until +/// its explicitly freed. +/// +/// Copying, cloning, or moving the allocator must not invalidate memory b= locks returned from this +/// allocator. A copied, cloned or even new allocator of the same type mus= t behave like the same +/// allocator, and any pointer to a memory buffer which is currently alloc= ated may be passed to any +/// other method of the allocator. +pub unsafe trait Allocator { + /// Allocate memory based on `layout` and `flags`. + /// + /// On success, returns a buffer represented as `NonNull<[u8]>` that s= atisfies the size an + /// alignment requirements of layout, but may exceed the requested siz= e. + /// + /// This function is equivalent to `realloc` when called with a NULL p= ointer and an `old_size` + /// of `0`. + fn alloc(&self, layout: Layout, flags: Flags) -> Result,= AllocError> { + // SAFETY: Passing a NULL pointer to `realloc` is valid by it's sa= fety requirements and asks + // for a new memory allocation. + unsafe { self.realloc(ptr::null_mut(), 0, layout, flags) } + } + + /// Re-allocate an existing memory allocation to satisfy the requested= `layout`. If the + /// requested size is zero, `realloc` behaves equivalent to `free`. + /// + /// If the requested size is larger than `old_size`, a successful call= to `realloc` guarantees + /// that the new or grown buffer has at least `Layout::size` bytes, bu= t may also be larger. + /// + /// If the requested size is smaller than `old_size`, `realloc` may or= may not shrink the + /// buffer; this is implementation specific to the allocator. + /// + /// On allocation failure, the existing buffer, if any, remains valid. + /// + /// The buffer is represented as `NonNull<[u8]>`. + /// + /// # Safety + /// + /// `ptr` must point to an existing and valid memory allocation create= d by this allocator + /// instance of a size of at least `old_size`. + /// + /// Additionally, `ptr` is allowed to be a NULL pointer; in this case = a new memory allocation is + /// created. + unsafe fn realloc( + &self, + ptr: *mut u8, + old_size: usize, + layout: Layout, + flags: Flags, + ) -> Result, AllocError>; + + /// Free an existing memory allocation. + /// + /// # Safety + /// + /// `ptr` must point to an existing and valid memory allocation create= d by this `Allocator` + /// instance. + unsafe fn free(&self, ptr: *mut u8) { + // SAFETY: `ptr` is guaranteed to be previously allocated with thi= s `Allocator` or NULL. + // Calling `realloc` with a buffer size of zero, frees the buffer = `ptr` points to. + let _ =3D unsafe { self.realloc(ptr, 0, Layout::new::<()>(), Flags= (0)) }; + } +} --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BC731B47B6 for ; Thu, 4 Jul 2024 17:08:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112907; cv=none; b=HxavxbywyrRUSRCfjLH8xdQqJCb1gNSjjmXyFwl3SrhaueJrMjIP4mZAI9f1aGFRp38R9mTGDD/JC1wrDKk0xVe0yzXm6+fKhV+AEqQFXLhG7qwZxIwlwz0N1MHiYH3R3IgM5Q+0LsGQY5k77CW4vNjTnadiLrxHUMfF75z+aoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112907; c=relaxed/simple; bh=QrynI0HoPy4Hny/wycemLcIhmp9fTzHnwd0bnDI3BXo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AGONQ9v77JDz5o0Ciz9k4nkxgs2GitgS1ftrPWQ2jKmEUwuF7a5Me51sjZCn0TNwQ7b2u2/gAVYTNh9JhIJRfmJzTeElSnntp9YtVNXwR94rT4SE2Zd57revv2QP6XfaOKxeZeECFdemiPDXimtf1VbwgPj63tl/gOdPPCvileU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ajTSJzYX; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ajTSJzYX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112905; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gkm1HsuIC/IJIdfFvL0dQb/JQUMIA7HW6TqPIuzm1+Y=; b=ajTSJzYXzvA/Md+u8p8ku6nYvSsWHpDFMx9TlFj7Kehhbe35bRqVOZzqBvI6sb5+MZi08R fx9k2mMHN1BPyGFwpa96BBv3z10A/QjnGP9ijZKV9Q7ntEzQnZMXM/SNrfL30cP0nD3EDO d2kywdeD0aeLzJ30OT8VwVvBnB4b9nA= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-w5O_m417POGJpg1mSheQmw-1; Thu, 04 Jul 2024 13:08:23 -0400 X-MC-Unique: w5O_m417POGJpg1mSheQmw-1 Received: by mail-lj1-f197.google.com with SMTP id 38308e7fff4ca-2ee8f22ef7cso8481301fa.2 for ; Thu, 04 Jul 2024 10:08:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112902; x=1720717702; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gkm1HsuIC/IJIdfFvL0dQb/JQUMIA7HW6TqPIuzm1+Y=; b=JBI78uWwgiXODIzkNH8jxO3RM2t/BcTWwpxxvCH/uN0k1fO3kRHD0Y4Ynh56zllMxq Zj3MSgSwgYslFtF/dJ3h7zTjYiVzWfFvrLLh4gudn/4czNWJd0tIM1neHV/Rp3Gy2PsS SBWr5Zhj59HjYL2zEQeQQG4pOreBOmYXBV8PhqzPh8lOZslra4YBmJXBY37JCQD5qPKB dGQNg0qrzMs4pOErPAVZbJ7AJjra6pZxRZKEeJlHt84MdUDh/+2AmE+DAFZxDqE0hNc+ orGkhmyoHbQ6NMUppp+GmBNdlTrPkpkhAl+fJXKEd5Z8BuqrQ1wE0lmNNqxHZG5hMRZW PfBA== X-Forwarded-Encrypted: i=1; AJvYcCVtXdTmqF3ZEeova8WIoNh+iNunuCDN9IWf+0Eb6+M9qlJGtIngxGiAVFZPF11WEXdefmdBLD4jOpVHZhN9dKsF80Szq2v61d+Axq20 X-Gm-Message-State: AOJu0YzSTx0/rIerB88K5vrFMA+u8spOxieBqcgucDDMh2DK4jJu296E Pmvv6JczeoBD08knJ8CvjeXcVqqVhvLDVFtL917gKASgvkxKv9bbTfKApT8HR0NdzMSCpG+0OOC 24Nh6ssgUvUjN8Riz83u39qRI+TbLuCuaVjS6EDTOLAo9eEiihovB0LVfj+mY9w== X-Received: by 2002:a05:6512:3aa:b0:52c:8fd7:2252 with SMTP id 2adb3069b0e04-52ea061f61emr1482808e87.11.1720112902213; Thu, 04 Jul 2024 10:08:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHC1w3veRR7ifL3/ieyNufl0zLqc3/LfgsQPz+jstYWmTdKHKy92qb6tBJMl0hm5NEL7o5XSA== X-Received: by 2002:a05:6512:3aa:b0:52c:8fd7:2252 with SMTP id 2adb3069b0e04-52ea061f61emr1482784e87.11.1720112901793; Thu, 04 Jul 2024 10:08:21 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a1d0b24sm31308165e9.3.2024.07.04.10.08.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:21 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 02/20] rust: alloc: separate `aligned_size` from `krealloc_aligned` Date: Thu, 4 Jul 2024 19:06:30 +0200 Message-ID: <20240704170738.3621-3-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Separate `aligned_size` from `krealloc_aligned`. Subsequent patches implement `Allocator` derivates, such as `Kmalloc`, that require `aligned_size` and replace the original `krealloc_aligned`. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc/allocator.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index 229642960cd1..49fb33cc18d9 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -8,13 +8,7 @@ =20 struct KernelAllocator; =20 -/// Calls `krealloc` with a proper size to alloc a new object aligned to `= new_layout`'s alignment. -/// -/// # Safety -/// -/// - `ptr` can be either null or a pointer which has been allocated by th= is allocator. -/// - `new_layout` must have a non-zero size. -pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, fl= ags: Flags) -> *mut u8 { +fn aligned_size(new_layout: Layout) -> usize { // Customized layouts from `Layout::from_size_align()` can have size <= align, so pad first. let layout =3D new_layout.pad_to_align(); =20 @@ -30,12 +24,28 @@ pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new= _layout: Layout, flags: F size =3D size.next_power_of_two(); } =20 + size +} + +/// Calls `krealloc` with a proper size to alloc a new object aligned to `= new_layout`'s alignment. +/// +/// # Safety +/// +/// - `ptr` can be either null or a pointer which has been allocated by th= is allocator. +/// - `new_layout` must have a non-zero size. +pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, fl= ags: Flags) -> *mut u8 { // SAFETY: // - `ptr` is either null or a pointer returned from a previous `k{re}= alloc()` by the // function safety requirement. // - `size` is greater than 0 since it's either a `layout.size()` (whi= ch cannot be zero // according to the function safety requirement) or a result from `n= ext_power_of_two()`. - unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, fla= gs.0) as *mut u8 } + unsafe { + bindings::krealloc( + ptr as *const core::ffi::c_void, + aligned_size(new_layout), + flags.0, + ) as *mut u8 + } } =20 unsafe impl GlobalAlloc for KernelAllocator { --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7962D1B3F06 for ; Thu, 4 Jul 2024 17:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112911; cv=none; b=Bx4DQiOBOuEtgBcNbq3bCw2p5bd+4bmWWiFWACLi5XOkt/jl43uqg2WPfft+QsGWobAjafJKrwsnb3k8y3QLnKbpDj4GGmMpfcjIeWkQlSmAwFwrZESeOVa9JKKNtgSARQyrwAQcQZ9ZXroDmkmEMoh/5M7SMtI6qr4liHwcr9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112911; c=relaxed/simple; bh=dBkn8uWErKq0NfiBMQ9moE7lJwn+ZFUPDGAulmb98hI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NK03iyWK7i9nDc0c015l9m1pZa/B6yemV05okCNuSmKI4FIPaBeum/r37B5ka5ZRnFr/kcqcZlnICnzmW6wp7Xv0Nw1IOtz40kBHUzTq0XnK2Hoc0gscHhe2+LwtMzwdOb9OvCX+LMeSFJmP/9XWbKW0KMZQfnAuHEMC7nbimkY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=faR4Ld11; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="faR4Ld11" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112908; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xi1xjBHaOdM6NCOm6B2REEcdukdUD5LuLilmDyDwG4g=; b=faR4Ld11T81gZuLnjE19OgU95cXwzI3YJJOL8rUDPDEDn5b5WDbwAO6ULcveWwIyxsKMjX 3wgPA17EMqk1rn9rzQgXlS2XB58FzunDghKTRONIrS1mtwrZk5tpz8jtLgWioYBH9xblm7 89CocErhU6BDXk2k4COehazOqNFXwfE= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-32-doAIwN3bOvGSNpLfYa0gVQ-1; Thu, 04 Jul 2024 13:08:27 -0400 X-MC-Unique: doAIwN3bOvGSNpLfYa0gVQ-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-367987cff30so601698f8f.1 for ; Thu, 04 Jul 2024 10:08:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112906; x=1720717706; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xi1xjBHaOdM6NCOm6B2REEcdukdUD5LuLilmDyDwG4g=; b=aptP8F5lQzmbNdjwnBeOmZP7HTXFH4KqC5XcBARKXRew1lPaUKklibmnZ2fKQiHu2Y JPezZYrkwNPnYR1i3Cab66iFHdeO7NpdjWc680j+TEscMRg6BdozaXkUfHLxQYJ6Clgn ysS/eVowtVSFdtDgQLRgsmbsODW7mGR0L7qf/9UjPThcsY+8/AhhIp3kEFm2MXj6Fp/9 I36eQmD1a4EiJnWlojdI1aPPIv/wWlhvvj0TWbLLUhzjEYEXQ1zGsOrpEYam4B8UaC4g KFIlQ6sojwLNjDLVWBzSOEasJpTU6o/UqdOMow1n0u03Ztk7VuASF3kfuUqA8J4WoeMz 3BGg== X-Forwarded-Encrypted: i=1; AJvYcCWfUlvQwfGFVlXn/Ivm/qGbOYZljbnb67f2qEZdxNMne6gjoT2vcYqbjtfIb9IiQxMJrUyjBjzCxtHnbXDNbGFXiQAfu5CLNcpPuyNg X-Gm-Message-State: AOJu0Yx2hhqve32+yfHnpWM00Kn/sFTSHLlFDWsEofyTDy6QGkLRrHlC x5a8IbFCGF8Rbm2v7u9Pn0lpZ8t4s6M66p+JlzWtJKuojJlhVCb6kZ2ZZdkDKY6PeTyAvTeyB5s b+eLuD9tYNZ8+sWpvO0+yprKhlP8coqlP4HwE6oSRn481tkl4ZojopIQfiIGMCw== X-Received: by 2002:adf:f548:0:b0:366:ec2c:8648 with SMTP id ffacd0b85a97d-3679dd66b0emr1473881f8f.43.1720112906043; Thu, 04 Jul 2024 10:08:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEZE9lqxekh8vlvO7Znvqy+xmMypbyEYcSxQDzUKYJCWAgpo4YD19f2xbFzHmbfg5HdXDdSSQ== X-Received: by 2002:adf:f548:0:b0:366:ec2c:8648 with SMTP id ffacd0b85a97d-3679dd66b0emr1473853f8f.43.1720112905720; Thu, 04 Jul 2024 10:08:25 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3679983882csm2704593f8f.78.2024.07.04.10.08.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:25 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 03/20] rust: alloc: rename `KernelAllocator` to `Kmalloc` Date: Thu, 4 Jul 2024 19:06:31 +0200 Message-ID: <20240704170738.3621-4-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Subsequent patches implement `Vmalloc` and `KVmalloc` allocators, hence align `KernelAllocator` to this naming scheme. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc/allocator.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index 49fb33cc18d9..e47ab8fe21ab 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -6,7 +6,7 @@ use core::alloc::{GlobalAlloc, Layout}; use core::ptr; =20 -struct KernelAllocator; +struct Kmalloc; =20 fn aligned_size(new_layout: Layout) -> usize { // Customized layouts from `Layout::from_size_align()` can have size <= align, so pad first. @@ -48,7 +48,7 @@ pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_l= ayout: Layout, flags: F } } =20 -unsafe impl GlobalAlloc for KernelAllocator { +unsafe impl GlobalAlloc for Kmalloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero s= ize by the function safety // requirement. @@ -84,7 +84,7 @@ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { } =20 #[global_allocator] -static ALLOCATOR: KernelAllocator =3D KernelAllocator; +static ALLOCATOR: Kmalloc =3D Kmalloc; =20 // See . #[no_mangle] --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73BE61B6A53 for ; Thu, 4 Jul 2024 17:08:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112915; cv=none; b=kqobH00qtTRBSWM0Vwq+XEsleNvnQa1VktOtBB/7MvvHILGafaDKo9DsilTvlrtgIogh0s04BBsiX1nFLiEmSerjm0pYrCENTEIpq4RKU1sqshnSeDDmRUOQjgdkUJyoDF1Ob2Plnf8ZRmZ41Myel+Dy9L7Hke9aDLfIDUBueUE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112915; c=relaxed/simple; bh=aqDUDzMLL0KBfzNb+W57apl4KxEClGQPXZoBULsxmbE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tlxQ6ZlctdjyM996ByD+HOqjVOVDLKWIOKjdxKXnVzVGNY3cS113LMEKnGwGRzt4npVWT9LbGMsMdX5q6I/55uCJzPaoyk987+VW9e/1EBAaQ9XQgLrSTeVRdbPD+hloaRf2c6er29kOjCG167FAl6aDQaMNJa5jriESBLz+EuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=JUZxZ8wh; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="JUZxZ8wh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H4BR7jnFeoylsc8H3CWU/Zy5FjcYkLHilMYKh3x+8ho=; b=JUZxZ8wh6Bh8Um/+SOPGJFTcl7dfs1/fgxNfYkA6tV/lyhrDFNB3FKnYamWPBnrf/3xXVc AwmxsODby1V2hOTTeqhawQWqFu6f7YViJsm0KsJ56SA+XLhTOHn9nsAMGxF6ck/iW+vO14 XpUUFemt1nFTs3/r2IExJ8CWw8Mu5co= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-111-vNBs-4IpNmO5sNuyi0TJoQ-1; Thu, 04 Jul 2024 13:08:31 -0400 X-MC-Unique: vNBs-4IpNmO5sNuyi0TJoQ-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-36785e6c1e6so556696f8f.3 for ; Thu, 04 Jul 2024 10:08:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112910; x=1720717710; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H4BR7jnFeoylsc8H3CWU/Zy5FjcYkLHilMYKh3x+8ho=; b=nVD2EfSB4KDEuMa/cij4CZ5DIMgC4oi1uma3oGwiPuttT96zbM8dLiqlKHLLuoRmdl kbMcAlyHs0zqsxkG7tEGPCso+11DUlAmz0f4HEfem37+qi9FYI58ZD3lSbwjwgKMUnMm bP+whKeDVwJ0O/zpHLCEP/SmwUCylQxQVkTt08VtRgx1RpyTzbjY6+RvRbIQR+8JvJqY bvX9vYhG5YrRo/Umz3KIvOolKa/nmZ6GamCUDi1ezqWHYZxca2g9PEU5mE9YlLESM/N0 sp8J2rOM+fM44I2tPvEUJQll6OVHRMnjsQYZT+JZnNs+GFm7Uy6xWQsXaF6OZ2PAVv4m mX2w== X-Forwarded-Encrypted: i=1; AJvYcCXGAtlwnRYpR1lVSzit8JP1ad4B1FEAXNNClrBBqVk6A/mc4OEIPaPpaksbacP/QgznRD8sAkca/aFOSM3xvw3QuhZxWF6fS9YPlm0k X-Gm-Message-State: AOJu0YzkqgQpXBdiWsiilxBb88QMwqrCAte37oRzERdWMwZ1FGTnr2ne yBRkY2/rbjs1Qfch6Bzn1Nj54vQeFjTC90meNDEZb8JDSVQOIvbCCXdh6FVMT2GDy6s+lYipv5D kfT62YTdHScIP3nNA9qVeHV7J7IsueZBTZJ0Q59hfIo7kO7DnKVeyA8uzYBWDcw== X-Received: by 2002:adf:f28e:0:b0:367:4dce:1ff5 with SMTP id ffacd0b85a97d-3679dd36309mr1758609f8f.32.1720112909989; Thu, 04 Jul 2024 10:08:29 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFtFP0X2+rYgV0THjQz9OOrD6kATfOo+R0GkmOlrj+yr/SK3gwzL+dt1XCgyR3THktcbaONoQ== X-Received: by 2002:adf:f28e:0:b0:367:4dce:1ff5 with SMTP id ffacd0b85a97d-3679dd36309mr1758582f8f.32.1720112909619; Thu, 04 Jul 2024 10:08:29 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3678ed75772sm6030398f8f.62.2024.07.04.10.08.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:29 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 04/20] rust: alloc: implement `Allocator` for `Kmalloc` Date: Thu, 4 Jul 2024 19:06:32 +0200 Message-ID: <20240704170738.3621-5-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement `Allocator` for `Kmalloc`, the kernel's default allocator, typically used for objects smaller than page size. All memory allocations made with `Kmalloc` end up in `krealloc()`. It serves as the default allocator for the subsequently introduced types `KBox` and `KVec`. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 2 +- rust/kernel/alloc/allocator.rs | 74 ++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 462e00982510..8d79cc95dc1e 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -4,7 +4,7 @@ =20 #[cfg(not(test))] #[cfg(not(testlib))] -mod allocator; +pub mod allocator; pub mod box_ext; pub mod vec_ext; =20 diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index e47ab8fe21ab..b7c0490f6415 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -5,9 +5,18 @@ use super::{flags::*, Flags}; use core::alloc::{GlobalAlloc, Layout}; use core::ptr; +use core::ptr::NonNull; =20 -struct Kmalloc; +use crate::alloc::{AllocError, Allocator}; +use crate::bindings; =20 +/// The contiguous kernel allocator. +/// +/// The contiguous kernel allocator only ever allocates physically contigu= ous memory through +/// `bindings::krealloc`. +pub struct Kmalloc; + +/// Returns a proper size to alloc a new object aligned to `new_layout`'s = alignment. fn aligned_size(new_layout: Layout) -> usize { // Customized layouts from `Layout::from_size_align()` can have size <= align, so pad first. let layout =3D new_layout.pad_to_align(); @@ -27,7 +36,7 @@ fn aligned_size(new_layout: Layout) -> usize { size } =20 -/// Calls `krealloc` with a proper size to alloc a new object aligned to `= new_layout`'s alignment. +/// Calls `krealloc` with a proper size to alloc a new object. /// /// # Safety /// @@ -48,20 +57,54 @@ pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new= _layout: Layout, flags: F } } =20 +unsafe impl Allocator for Kmalloc { + unsafe fn realloc( + &self, + old_ptr: *mut u8, + _old_size: usize, + layout: Layout, + flags: Flags, + ) -> Result, AllocError> { + let size =3D aligned_size(layout); + + // SAFETY: `src` is guaranteed to point to valid memory with a siz= e of at least + // `old_size`, which was previously allocated with this `Allocator= ` or NULL. + let raw_ptr =3D unsafe { + // If `size =3D=3D 0` and `old_ptr !=3D NULL` `krealloc()` fre= es the memory behind the + // pointer. + bindings::krealloc(old_ptr.cast(), size, flags.0).cast() + }; + + let ptr =3D if size =3D=3D 0 { + NonNull::dangling() + } else { + NonNull::new(raw_ptr).ok_or(AllocError)? + }; + + Ok(NonNull::slice_from_raw_parts(ptr, size)) + } +} + unsafe impl GlobalAlloc for Kmalloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero s= ize by the function safety - // requirement. - unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL) } + let this: &dyn Allocator =3D self; + + match this.alloc(layout, GFP_KERNEL) { + Ok(ptr) =3D> ptr.as_ptr().cast(), + Err(_) =3D> ptr::null_mut(), + } } =20 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - unsafe { - bindings::kfree(ptr as *const core::ffi::c_void); - } + // SAFETY: The safety requirements of `dealloc` are a superset of = the ones of + // `Allocator::free`. + unsafe { self.free(ptr) } } =20 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize= ) -> *mut u8 { + let this: &dyn Allocator =3D self; + let old_size =3D layout.size(); + // SAFETY: // - `new_size`, when rounded up to the nearest multiple of `layou= t.align()`, will not // overflow `isize` by the function safety requirement. @@ -73,13 +116,20 @@ unsafe fn realloc(&self, ptr: *mut u8, layout: Layout,= new_size: usize) -> *mut // requirement. // - the size of `layout` is not zero because `new_size` is not ze= ro by the function safety // requirement. - unsafe { krealloc_aligned(ptr, layout, GFP_KERNEL) } + // - `old_size` represents the memory that needs to be preserved. + match unsafe { this.realloc(ptr, old_size, layout, GFP_KERNEL) } { + Ok(ptr) =3D> ptr.as_ptr().cast(), + Err(_) =3D> ptr::null_mut(), + } } =20 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero s= ize by the function safety - // requirement. - unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL | __= GFP_ZERO) } + let this: &dyn Allocator =3D self; + + match this.alloc(layout, GFP_KERNEL | __GFP_ZERO) { + Ok(ptr) =3D> ptr.as_ptr().cast(), + Err(_) =3D> ptr::null_mut(), + } } } =20 --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 859891B6A7F for ; Thu, 4 Jul 2024 17:08:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112919; cv=none; b=txsKIwbDVgBAvoDcHLkRC3RBpbXytp5qY/4ctGq+NWnzEBRUR6QoN+RbwYKIKJBlroauHpZcHZG6/qK2dzZhFwMzwjSk1yh436b1XxU/4RGOrHBugZGlGy2vOpuV29Hbv/abGbx7JJnt0Kd1nfIzroqbtCKyatAKDWYkH0S06wQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112919; c=relaxed/simple; bh=DCq3JdKHMv1BQsHzkac2p/ZW/zPdLP0o1nouh+/SEUw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGGa78/1xkkKLdbUQ1Xv8M+DMFt8wNsYhB81GVROWyeacia+W1gyvnplQYOPojIYTnLZQSpcIB+5xYUf+AF/FyTemKDY5uU+js+snh51aHNEI8LcWBshU7uGS/w+9TfTDrpPozaNOxYqusZ7/0CFGh2fk47i2w2J2kH+MYK7sT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=WJFCrsst; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WJFCrsst" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112916; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DNNJhnlE4FEesPjTYaQmJVB4plwJ5MVZycKMsnB4Uog=; b=WJFCrsstoU3nmRvuX4muh0pOezjohNniLpp035v/VRgw8aOS0mgPjFVhs5MZCBaOEQV5mo 2NPye1Yc6U96aPAsIhkhaUXEZpZysmoEepfgjxkyifWV7foh7UaX0CWsHUkROv2PUZX2BP SdGhnrLYOsJd4DXyrK7JoxZYT73+7uI= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-307-yqdXWKVnN4CZnc-lP7cigw-1; Thu, 04 Jul 2024 13:08:34 -0400 X-MC-Unique: yqdXWKVnN4CZnc-lP7cigw-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4257f95fe85so6078245e9.1 for ; Thu, 04 Jul 2024 10:08:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112914; x=1720717714; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DNNJhnlE4FEesPjTYaQmJVB4plwJ5MVZycKMsnB4Uog=; b=Y00bbwZ2aWn0lsyosyhTG84rtUXVrHgdYekRAa3R7ZsEau8NXgqzV37RQ2mMD4sGUB PFIzAhy/fvazkNut1po0OlecgFljtPfZ19X1xLGQFdDxH7YhbebuAeS0wtqYR5AOCKSe WLKuX6JCgMgVd4kLbhUGc0ghudmW7Z2crQwJn3GOWVh2WPY6E7BLwcAhokHUdbVLjClU XaHGTxRqfaIlHCEn8FcoIHc1dwFArHWFTIILqi2eTsJ9wHC4TkD3g4TOCKOpUHU1rYPc ER3nV4JJy6Gn3d0P/ai8IJ4BWm9Gzm0ZZXVIoYyAJWgr6i4lkSzOVhEqfkeyfRyg6tpq LACQ== X-Forwarded-Encrypted: i=1; AJvYcCWCDZVBF9/iLcsdKYi41IWYiAiBREdfBz3EPP89utb1W0DSs46B0i8KSYjOgvzbxxoxqawrog7Bdz3LlmvSM6C+wOHEOMGzVA/fywW9 X-Gm-Message-State: AOJu0YzhbP5U5+ybQJ4EEhNwVSE1R0Ntrwi+vmFRCq3ez+3THmu3DL70 PA4iTDvgSbQ9V2I2V3fWEzmlVRYrvMY9jOYMvwS1OHu9zotI2fTSAKFTjNDDj5BsDPH+eSh82IE XQRRuzSEHo2kCSwFPyZsSGBWl0Kcl1FtPltNCp7lPbYNLO8lykKGKJCcxiRndeA== X-Received: by 2002:a05:600c:47ca:b0:425:7853:e2db with SMTP id 5b1f17b1804b1-4264a468ab2mr16629595e9.29.1720112913774; Thu, 04 Jul 2024 10:08:33 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG1lCENdfe+k6G48i1rTSjNdqGggpx5cLlnXPcGT3EGfuFdPEzBXdckhXeQIDSmC2fNB/1RDA== X-Received: by 2002:a05:600c:47ca:b0:425:7853:e2db with SMTP id 5b1f17b1804b1-4264a468ab2mr16629445e9.29.1720112913503; Thu, 04 Jul 2024 10:08:33 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a283577sm31163725e9.44.2024.07.04.10.08.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:33 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 05/20] rust: alloc: add module `allocator_test` Date: Thu, 4 Jul 2024 19:06:33 +0200 Message-ID: <20240704170738.3621-6-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" `Allocator`s, such as `Kmalloc`, will be used by e.g. `KBox` and `KVec` in subsequent patches, and hence this dependency propagates throughout the whole kernel. Add the `allocator_test` module that provides an empty implementation for all `Allocator`s in the kernel, such that we don't break the `rusttest` make target in subsequent patches. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 9 +++++++-- rust/kernel/alloc/allocator_test.rs | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 rust/kernel/alloc/allocator_test.rs diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 8d79cc95dc1e..46ebdd059c92 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -2,12 +2,17 @@ =20 //! Extensions to the [`alloc`] crate. =20 -#[cfg(not(test))] -#[cfg(not(testlib))] +#[cfg(not(any(test, testlib)))] pub mod allocator; pub mod box_ext; pub mod vec_ext; =20 +#[cfg(any(test, testlib))] +pub mod allocator_test; + +#[cfg(any(test, testlib))] +pub use self::allocator_test as allocator; + /// Indicates an allocation error. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct AllocError; diff --git a/rust/kernel/alloc/allocator_test.rs b/rust/kernel/alloc/alloca= tor_test.rs new file mode 100644 index 000000000000..3a0abe65491d --- /dev/null +++ b/rust/kernel/alloc/allocator_test.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 + +#![allow(missing_docs)] + +use super::{AllocError, Allocator, Flags}; +use core::alloc::Layout; +use core::ptr::NonNull; + +pub struct Kmalloc; + +unsafe impl Allocator for Kmalloc { + unsafe fn realloc( + &self, + _old_ptr: *mut u8, + _old_size: usize, + _layout: Layout, + _flags: Flags, + ) -> Result, AllocError> { + panic!(); + } +} --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 576F01BB6A2 for ; Thu, 4 Jul 2024 17:08:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112922; cv=none; b=DyFMDpF3gBg1pWZ2lQTVJhFLe6nbNvh5Mrc6IvdNYgG+YJcRlCZs9S5X/JqZaAHGolp0cXhNoPLOHS804yJSrzHUGyaqYXo8fUQFHeVGsNnjNJRHkTix3I1eNopZ8nEC5i5SJ4xHoEG2oDkS3wB/2WS3kDAupDW4Y2uWLU+Rd40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112922; c=relaxed/simple; bh=YcnAH3SHZXROeNoMHnipvFfals1BnUzQ96nTlnvMQFo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MszTlQbOoA7Ivx9pX7VOUhbfqwskhu1F0bOAIGYstnJo3CcxSCayZ75nqc7ohB25Va9UlEL1qE631jbOpZpHE+wc9ZLX6WMI4EUIDQAU4TdHVibbJRMxuM7yfjpTIUYKkYxl6hip0AZ1z2xageD5XZ1EF0hGT4lSrcK3sqpFzWQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Jj4QXqQY; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Jj4QXqQY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112920; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=u0UMICwsMRzMsfA9s19JVB8HcVWOB39iLX8GByK/zHc=; b=Jj4QXqQYg9Db1teo87LBqhfTfKnhttYn7Mim+T+cFOcMIASjJ5UbvyQ96jkn92GWF/Znrg iq+bmKjX9Tl+pEz1UdMroOoDgpub8bcAB8P/Us5H36+wmffcZuwMjiVYEd9AaStyw7cTEB tSmdR0uOgya5hxxkkoMRYivPgHX8nWY= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-BAUgnQgJPLmzE_HnGCcwMw-1; Thu, 04 Jul 2024 13:08:39 -0400 X-MC-Unique: BAUgnQgJPLmzE_HnGCcwMw-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-36792df120fso658730f8f.1 for ; Thu, 04 Jul 2024 10:08:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112918; x=1720717718; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=u0UMICwsMRzMsfA9s19JVB8HcVWOB39iLX8GByK/zHc=; b=LDhQEdc+XUbsNw6BIN9LU7XHy6CSusn6+Msklt/xekLepj8ymRZGecX/gn0DN7vbEF ulvfleGkXAQ0KuOGnSeFfIC1mQZ9Zgkufj62yuq4K5f4pDZaLyrciThtXgAwAkk3y0yz CvcC2s3gb82xK7AuohO5j4AnbYJP61oK7sfORlH+DIIxQOEEOERJPYjiALmNO2wHVLoB 2Lv1hOQ4btIFjhxVIklnl3qqPq8Ej6KNiCvRz3MWSt4Jn1EZG61/chQffYmnaNXIz39w ItcDzqKEjmzbHxJuOk/DR9PJ7H6jnMozAmZUzqPcCEUooG/ONEpwk1UqM3nJBXe+a8tO LFPw== X-Forwarded-Encrypted: i=1; AJvYcCVym65xGZhhiOmzhmugj5we18DjztCP4VllcL2ebcO6R2tLtRB/SfAdGbIaojh34xWgf8BQEhRG27RaUtoRUQSiuEVtNpuvtT/TrTby X-Gm-Message-State: AOJu0YyBX7ffoSayD5TZC1FA/oTavqA24h1wK11PEJRTAzqM13ntGX6Q rqPiKyTMCfzfbrHm+BXi1nxOeg8K8xMEpM2Zi1Z2tcOTVNsJ/uznJTSojF6UOQTrr8rOfURULcj nv9FXcb93rmnY2GzjfYo2tVSttXVcp+CjJsu+1ndpEmNRmWiXqmoX3IPBKKun9A== X-Received: by 2002:a05:6000:12c6:b0:367:91cf:e890 with SMTP id ffacd0b85a97d-3679dd10283mr1823258f8f.6.1720112917799; Thu, 04 Jul 2024 10:08:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF/XJEdVUhXEyatK6ngjqfp7NJ4Le1ciarBr+9Y1EF175deeq20/plyxZJPo3uVQ0XayyddFQ== X-Received: by 2002:a05:6000:12c6:b0:367:91cf:e890 with SMTP id ffacd0b85a97d-3679dd10283mr1823239f8f.6.1720112917535; Thu, 04 Jul 2024 10:08:37 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367a3016f8bsm877280f8f.46.2024.07.04.10.08.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:36 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 06/20] rust: alloc: remove `krealloc_aligned` Date: Thu, 4 Jul 2024 19:06:34 +0200 Message-ID: <20240704170738.3621-7-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that we have `Allocator` for `Kmalloc` in place, remove explicit calls to `krealloc_aligned` and get rid of `krealloc_aligned` itself. `bindings::krealloc` should only be called from `Kmalloc::realloc`. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc/allocator.rs | 21 --------------------- rust/kernel/alloc/box_ext.rs | 13 ++++--------- rust/kernel/alloc/vec_ext.rs | 23 +++++++++++++---------- 3 files changed, 17 insertions(+), 40 deletions(-) diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index b7c0490f6415..1860cb79b875 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -36,27 +36,6 @@ fn aligned_size(new_layout: Layout) -> usize { size } =20 -/// Calls `krealloc` with a proper size to alloc a new object. -/// -/// # Safety -/// -/// - `ptr` can be either null or a pointer which has been allocated by th= is allocator. -/// - `new_layout` must have a non-zero size. -pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, fl= ags: Flags) -> *mut u8 { - // SAFETY: - // - `ptr` is either null or a pointer returned from a previous `k{re}= alloc()` by the - // function safety requirement. - // - `size` is greater than 0 since it's either a `layout.size()` (whi= ch cannot be zero - // according to the function safety requirement) or a result from `n= ext_power_of_two()`. - unsafe { - bindings::krealloc( - ptr as *const core::ffi::c_void, - aligned_size(new_layout), - flags.0, - ) as *mut u8 - } -} - unsafe impl Allocator for Kmalloc { unsafe fn realloc( &self, diff --git a/rust/kernel/alloc/box_ext.rs b/rust/kernel/alloc/box_ext.rs index 829cb1c1cf9e..1aeae02c147e 100644 --- a/rust/kernel/alloc/box_ext.rs +++ b/rust/kernel/alloc/box_ext.rs @@ -33,24 +33,19 @@ fn new_uninit(_flags: Flags) -> Result>, AllocError> { #[cfg(not(any(test, testlib)))] fn new_uninit(flags: Flags) -> Result>, AllocError>= { let ptr =3D if core::mem::size_of::>() =3D=3D 0 { - core::ptr::NonNull::<_>::dangling().as_ptr() + core::ptr::NonNull::dangling() } else { + let alloc: &dyn super::Allocator =3D &super::allocator::Kmallo= c; let layout =3D core::alloc::Layout::new::>(); =20 // SAFETY: Memory is being allocated (first arg is null). The = only other source of // safety issues is sleeping on atomic context, which is addre= ssed by klint. Lastly, // the type is not a SZT (checked above). - let ptr =3D - unsafe { super::allocator::krealloc_aligned(core::ptr::nul= l_mut(), layout, flags) }; - if ptr.is_null() { - return Err(AllocError); - } - - ptr.cast::>() + alloc.alloc(layout, flags)?.cast() }; =20 // SAFETY: For non-zero-sized types, we allocate above using the g= lobal allocator. For // zero-sized types, we use `NonNull::dangling`. - Ok(unsafe { Box::from_raw(ptr) }) + Ok(unsafe { Box::from_raw(ptr.as_ptr()) }) } } diff --git a/rust/kernel/alloc/vec_ext.rs b/rust/kernel/alloc/vec_ext.rs index e9a81052728a..bf277976ed38 100644 --- a/rust/kernel/alloc/vec_ext.rs +++ b/rust/kernel/alloc/vec_ext.rs @@ -118,6 +118,7 @@ fn reserve(&mut self, additional: usize, _flags: Flags)= -> Result<(), AllocError =20 #[cfg(not(any(test, testlib)))] fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), A= llocError> { + let alloc: &dyn super::Allocator =3D &super::allocator::Kmalloc; let len =3D self.len(); let cap =3D self.capacity(); =20 @@ -145,16 +146,18 @@ fn reserve(&mut self, additional: usize, flags: Flags= ) -> Result<(), AllocError> =20 // SAFETY: `ptr` is valid because it's either NULL or comes from a= previous call to // `krealloc_aligned`. We also verified that the type is not a ZST. - let new_ptr =3D unsafe { super::allocator::krealloc_aligned(ptr.ca= st(), layout, flags) }; - if new_ptr.is_null() { - // SAFETY: We are just rebuilding the existing `Vec` with no c= hanges. - unsafe { rebuild(self, old_ptr, len, cap) }; - Err(AllocError) - } else { - // SAFETY: `ptr` has been reallocated with the layout for `new= _cap` elements. New cap - // is greater than `cap`, so it continues to be >=3D `len`. - unsafe { rebuild(self, new_ptr.cast::(), len, new_cap) }; - Ok(()) + match unsafe { alloc.realloc(ptr.cast(), cap, layout, flags) } { + Ok(ptr) =3D> { + // SAFETY: `ptr` has been reallocated with the layout for = `new_cap` elements. + // `new_cap` is greater than `cap`, so it continues to be = >=3D `len`. + unsafe { rebuild(self, ptr.as_ptr().cast(), len, new_cap) = }; + Ok(()) + } + Err(err) =3D> { + // SAFETY: We are just rebuilding the existing `Vec` with = no changes. + unsafe { rebuild(self, old_ptr, len, cap) }; + Err(err) + } } } } --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2867D1BC089 for ; Thu, 4 Jul 2024 17:08:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112926; cv=none; b=OdHyt2/t/hE6zNTNGietjHsilvFxJNfSX8jc9xj3aFN4ruKUbG17SBqKAsKggwx1P1R58hV5WrQoLL7SLMbilCJPNoydkJlavGAatKV+flwXbsWwaeYjMu/ILj3x4oFsTjW2U8VhZNX832jpimE/weoeIjTYYTYrsxCikRd7sWY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112926; c=relaxed/simple; bh=MmT2mTIg7lD3LQpVQ6BofZ6b0wOersBEjYOE2yVnphM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kKCsCQ/bVHgQ3TRpEU5VAlA78zrbsl3bsjMCTg5hIXFf9fr8Qqe/yaHdGWi6SLVe0Rgi2BhLC1EsEr9hxWtXOg/wnMlxX85CoiiRTNz/w+uERJM4TmpYjd/FzZFEc1ou+SCYooMwgx+6UEJK0Jp5Zem+WRukeUbXbLV6Gh7uDdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=XN2pfmFg; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="XN2pfmFg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112924; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Kxr2ZwkBcEiYjaLoRj6Vm8ZHty9ueyrSMs+jrT+4p3E=; b=XN2pfmFgC4NFpae5hNlbK4BSLSNoZN2JPNfu5Dcl8qu/7hwxyiJxSk4hQizJ79Us36+eld bSjC0V/JEIiK3iXeRwHMbInztRINkn/yi1rDRhrNZQwtPiERuwH2nDfxty/Ol+VNMwdbHZ 4LcjZS5dBIHbGQtBusmnBeShTpNJIGo= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-342-8SljsF9ZN9aiTyLE0zzwXg-1; Thu, 04 Jul 2024 13:08:42 -0400 X-MC-Unique: 8SljsF9ZN9aiTyLE0zzwXg-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4257a75193aso6150205e9.1 for ; Thu, 04 Jul 2024 10:08:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112922; x=1720717722; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Kxr2ZwkBcEiYjaLoRj6Vm8ZHty9ueyrSMs+jrT+4p3E=; b=U/Zjx9G6r2qqDy8hj99U6NeT1AepC74l5lig7ZJgHVC50/W/mVGfwv+dGfRvyJ3YJB +iG/fw/4lWCz7m1MvQI1DGXnF12dNpWpE/NK5imY9dKQFNj6CK2FiIOE/Xf4H0dqqKke ziVLCnafPV4thT/E/2FO2BNYV+PWHh9PDq+8kDoDSNm/t+sznIG4qh5WbBPb3bvJ7M8q qVILBiq61QhDFfeb6wCuXqRZ8zl61p+ZeKGd01XS2BnblgM22egF3pa1Y0Nijj4jJiBc 6G/BWW9auRLhTe+cLppCpoSqYwMTPYMmrjVRqhyK6L7ou2SuUjiML0yD/n88CuTe6Tea 5wXA== X-Forwarded-Encrypted: i=1; AJvYcCXqyBLKMmFUTl57N9ru4dWgcH3BuzewiGJ5vMXu8KshrSVJ9FFtrKqie6dKk0pTmLl1iez7kvVRQCVJCMVnEfa65hzXm1A0OWzdXk7l X-Gm-Message-State: AOJu0Yy1cxQlExXz1ZKvp657fxVjFCqtlIpaqjBu+h+60iPznOEZept/ rqe2POGyouAuyhM+jql7hTyIT4j+uls2s8c3/I89TSBoHKe4TnKFVBzrIQhzjKmYtlkMQ8xhkoS aFS0ga7JoFRksRdafuh+d3EhPt1SCvi0nRDJ5x6Kvk79HwmtqH7P84Mn4/+CLyg== X-Received: by 2002:a05:600c:4f88:b0:424:ad14:6b79 with SMTP id 5b1f17b1804b1-4264a3cc8bdmr13990895e9.8.1720112921744; Thu, 04 Jul 2024 10:08:41 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF1VJwx5uKuQN/O8iZw/4yKAqhZVwMwMz3EKnS+JDkXDZHxAy/WJXVoREQUOWvD5/92MPuUDA== X-Received: by 2002:a05:600c:4f88:b0:424:ad14:6b79 with SMTP id 5b1f17b1804b1-4264a3cc8bdmr13990825e9.8.1720112921452; Thu, 04 Jul 2024 10:08:41 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264d5101ffsm17492075e9.16.2024.07.04.10.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:41 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 07/20] rust: alloc: implement `Vmalloc` allocator Date: Thu, 4 Jul 2024 19:06:35 +0200 Message-ID: <20240704170738.3621-8-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement `Allocator` for `Vmalloc`, the kernel's virtually contiguous allocator, typically used for larger objects, (much) larger than page size. All memory allocations made with `Vmalloc` end up in `__vmalloc_noprof()`; all frees in `vfree()`. Signed-off-by: Danilo Krummrich --- rust/bindings/bindings_helper.h | 1 + rust/kernel/alloc/allocator.rs | 55 +++++++++++++++++++++++++++++ rust/kernel/alloc/allocator_test.rs | 1 + 3 files changed, 57 insertions(+) diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index ddb5644d4fd9..f10518045c16 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include =20 diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index 1860cb79b875..0a4f27c5c3a6 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -16,6 +16,12 @@ /// `bindings::krealloc`. pub struct Kmalloc; =20 +/// The virtually contiguous kernel allocator. +/// +/// The vmalloc allocator allocates pages from the page level allocator an= d maps them into the +/// contiguous kernel virtual space. +pub struct Vmalloc; + /// Returns a proper size to alloc a new object aligned to `new_layout`'s = alignment. fn aligned_size(new_layout: Layout) -> usize { // Customized layouts from `Layout::from_size_align()` can have size <= align, so pad first. @@ -112,6 +118,55 @@ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut = u8 { } } =20 +unsafe impl Allocator for Vmalloc { + unsafe fn realloc( + &self, + src: *mut u8, + old_size: usize, + layout: Layout, + flags: Flags, + ) -> Result, AllocError> { + let mut size =3D aligned_size(layout); + + let dst =3D if size =3D=3D 0 { + // SAFETY: `src` is guaranteed to be previously allocated with= this `Allocator` or NULL. + unsafe { bindings::vfree(src.cast()) }; + NonNull::dangling() + } else if size <=3D old_size { + size =3D old_size; + NonNull::new(src).ok_or(AllocError)? + } else { + // SAFETY: `src` is guaranteed to point to valid memory with a= size of at least + // `old_size`, which was previously allocated with this `Alloc= ator` or NULL. + let dst =3D unsafe { bindings::__vmalloc_noprof(size as u64, f= lags.0) }; + + // Validate that we actually allocated the requested memory. + let dst =3D NonNull::new(dst.cast()).ok_or(AllocError)?; + + if !src.is_null() { + // SAFETY: `src` is guaranteed to point to valid memory wi= th a size of at least + // `old_size`; `dst` is guaranteed to point to valid memor= y with a size of at least + // `size`. + unsafe { + core::ptr::copy_nonoverlapping( + src, + dst.as_ptr(), + core::cmp::min(old_size, size), + ) + }; + + // SAFETY: `src` is guaranteed to be previously allocated = with this `Allocator` or + // NULL. + unsafe { bindings::vfree(src.cast()) } + } + + dst + }; + + Ok(NonNull::slice_from_raw_parts(dst, size)) + } +} + #[global_allocator] static ALLOCATOR: Kmalloc =3D Kmalloc; =20 diff --git a/rust/kernel/alloc/allocator_test.rs b/rust/kernel/alloc/alloca= tor_test.rs index 3a0abe65491d..b2d7db492ba6 100644 --- a/rust/kernel/alloc/allocator_test.rs +++ b/rust/kernel/alloc/allocator_test.rs @@ -7,6 +7,7 @@ use core::ptr::NonNull; =20 pub struct Kmalloc; +pub type Vmalloc =3D Kmalloc; =20 unsafe impl Allocator for Kmalloc { unsafe fn realloc( --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C90271BF31E for ; Thu, 4 Jul 2024 17:08:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112930; cv=none; b=j+izp/VhzaMCvpxv+nmbdF3aj+TsT9siajSzzh2tar8ZVkLMbO8cIzVkG8nyPJf1yQfx19WXJSUZtmFpbtlqh7eSNRt7N8I9r9PDpggMloThCUkzT7LMRZdTgwYlYtURUrk/fm37DlbiXVTAmYgMN9REJqNUXl0UZBYz6UfJLVE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112930; c=relaxed/simple; bh=E7ojxsq33F6ZnnbOXdj2GEcN3gFVpL3aaByghHTyjMY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TO/KzFLxRpdmweCivuyaFT+GKBuTmM8RlZjX7c+wiy7DGmuMVpRnLmA7NjvdRP0zMCVDm5k3vX33UPSTXIGM2VFtygNCmzQddLDO0UvCxxT5/kgDz0TMzgo/Nhpbaok6auRBpaXruzYn5FUGi90WNeCjU5HJTCwtBlZiuXJby4I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=VZQmoSB5; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="VZQmoSB5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112927; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VyIj9wqWP+H3az8I4qjKuL0QiLtMtnLk/T2lFXWq4Zg=; b=VZQmoSB5Zd60W/LFf5YyxdeWnKRqtL7d+u5+w0GcHt5Bc5y2wyH/VJP07q0UlZV0XjbFXk pXRskIay9Z4kJ4Y5azc5OOpJ0lUbb8WqG43mfX4KGfJfD35+T/Wsni9SwTqlXj4GKwkoqW t5BjcymIELe41um5+bsK0WbxtP795w4= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-444-Ibxbz3qnObeEXgLhtKGBfw-1; Thu, 04 Jul 2024 13:08:46 -0400 X-MC-Unique: Ibxbz3qnObeEXgLhtKGBfw-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4257f95fe85so6079305e9.1 for ; Thu, 04 Jul 2024 10:08:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112925; x=1720717725; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VyIj9wqWP+H3az8I4qjKuL0QiLtMtnLk/T2lFXWq4Zg=; b=fSryI6qxMxqV6/UQGgW0Qqqu8BRA0exQ0O0j1Lh1KqwQR5DkbCqQEKkstutKJrxqhC GX9qJHZm1pNHfuFOobgC3+QnroYTxG/24rO8lkR5W+ZWGHSBCB1XY1HnoBzB/rRNlPa+ mLXmJT+FT6HzhX3q6wrIFF6dJ8wkL4R404ifTvTxYbvT/RQlXOio1jFOKRNGmqxskk6d L2psSK+fMRofIg8a0lzar0F9Xpr63Hb+dIPyyq5NQi5xL2R3l2ZDVY6GyWDmGrUm7Kd3 XARzVrkMzihJgyrnzwSOVPymdtcM0BH9uO69PhzS2FwN5ClsnH6xHN+jMvYXouqD/DcT HL+w== X-Forwarded-Encrypted: i=1; AJvYcCWRuYeQsQt3CYOGu9GtWHDJ31Rpkz9cSkcbv+sfDxZktwbzHVXa724fGv0lbsr78jfw4gPnEJ5KYovZKCwabksJLakKSHdYFrxXwLXl X-Gm-Message-State: AOJu0YwFKg37QyXgkU14QKEdqlsDr/6FLqC6MtfaKkvRiKaxIAVxcCAV J9hVscXh8iYimcZAGIIA6gJfmC1xeTwMWsGySjiSNENfcplTOAycb+vaBqYIPr3bMG0k8y30yi0 bxJxGTZkwd63OUTDsg56pHH0gWJ7hVevXgm8e4S8/SLCaUvBdnsRCDgUIyiI+tg== X-Received: by 2002:a05:600c:4205:b0:424:e04b:88f9 with SMTP id 5b1f17b1804b1-4264a3d882emr19468255e9.3.1720112925504; Thu, 04 Jul 2024 10:08:45 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHfI/OG2k4CkgNKhoBfG0TFM/3DwBzLEJDiB1KuYfjIallxq+of5uFapJbWq2WqSV8EV+r/zg== X-Received: by 2002:a05:600c:4205:b0:424:e04b:88f9 with SMTP id 5b1f17b1804b1-4264a3d882emr19468185e9.3.1720112925222; Thu, 04 Jul 2024 10:08:45 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a1d16b0sm30529065e9.7.2024.07.04.10.08.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:44 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 08/20] rust: alloc: implement `KVmalloc` allocator Date: Thu, 4 Jul 2024 19:06:36 +0200 Message-ID: <20240704170738.3621-9-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement `Allocator` for `KVmalloc`, an `Allocator` that tries to allocate memory wth `kmalloc` first and, on failure, falls back to `vmalloc`. All memory allocations made with `KVmalloc` end up in `kvrealloc_noprof()`; all frees in `kvfree()`. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc/allocator.rs | 35 +++++++++++++++++++++++++++++ rust/kernel/alloc/allocator_test.rs | 1 + 2 files changed, 36 insertions(+) diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index 0a4f27c5c3a6..d561c594cc7f 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -22,6 +22,12 @@ /// contiguous kernel virtual space. pub struct Vmalloc; =20 +/// The kvmalloc kernel allocator. +/// +/// Attempt to allocate physically contiguous memory, but upon failure, fa= ll back to non-contiguous +/// (vmalloc) allocation. +pub struct KVmalloc; + /// Returns a proper size to alloc a new object aligned to `new_layout`'s = alignment. fn aligned_size(new_layout: Layout) -> usize { // Customized layouts from `Layout::from_size_align()` can have size <= align, so pad first. @@ -167,6 +173,35 @@ unsafe fn realloc( } } =20 +unsafe impl Allocator for KVmalloc { + unsafe fn realloc( + &self, + old_ptr: *mut u8, + old_size: usize, + layout: Layout, + flags: Flags, + ) -> Result, AllocError> { + let size =3D aligned_size(layout); + + let ptr =3D if size =3D=3D 0 { + // SAFETY: `old_ptr` is guaranteed to be previously allocated = with this `Allocator` or + // NULL. + unsafe { bindings::kvfree(old_ptr.cast()) }; + NonNull::dangling() + } else { + // SAFETY: `old_ptr` is guaranteed to point to valid memory wi= th a size of at least + // `old_size`, which was previously allocated with this `Alloc= ator` or NULL. + let raw_ptr =3D unsafe { + bindings::kvrealloc_noprof(old_ptr.cast(), old_size, size,= flags.0).cast() + }; + + NonNull::new(raw_ptr).ok_or(AllocError)? + }; + + Ok(NonNull::slice_from_raw_parts(ptr, size)) + } +} + #[global_allocator] static ALLOCATOR: Kmalloc =3D Kmalloc; =20 diff --git a/rust/kernel/alloc/allocator_test.rs b/rust/kernel/alloc/alloca= tor_test.rs index b2d7db492ba6..f0e96016b196 100644 --- a/rust/kernel/alloc/allocator_test.rs +++ b/rust/kernel/alloc/allocator_test.rs @@ -8,6 +8,7 @@ =20 pub struct Kmalloc; pub type Vmalloc =3D Kmalloc; +pub type KVmalloc =3D Kmalloc; =20 unsafe impl Allocator for Kmalloc { unsafe fn realloc( --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94EA51C092E for ; Thu, 4 Jul 2024 17:08:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112935; cv=none; b=Md1clHZqVxRwpRiQcghJos/wY+VG38lsuHPyr/SYvCFT3Xa3c/4TjLufC/WnLI0d1/PG3dv++/k1NorbML97JfCXnrBZOs/9u4OQpa0ofaknZ0yo/VANSpTgwg+y2ZaRq65hkMj9MoTCeVdZw4jhhw7Wx9HXagopDqL4hFk+Ynw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112935; c=relaxed/simple; bh=dGm8d+PRxMNqkrwuSVGI4AqzVqqw/jVLlF0OhXEGCEw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ijv+yYrsfHmadgtvOiO752Rvs6uY54VM+VKhJmZUVNh2vIZd8h6MsWCJu7onlAEcaC15hwVQea3fuCEDA4FNBWELWpOfbkUbAUbvR0DAaLaemFm28Sdt8L4EZ7kmq5c0+HISbAEVz8fDVgDslg6DmdQPs54BwIKUysAJhJngXo8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=G+zZsr9P; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="G+zZsr9P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BQxAYuE6n+/DH+OguL+f/xlAy+kzOF6Lw0v+HCA+hEE=; b=G+zZsr9P4VjgangClml5rN0ewlr9S+wL20maOhTV8UapqWRPVTkPTkb/U3/3/d85iOQrh2 082215Uc3KgdBfdkdffqR5/VUV2SQYpSrkLsOyvR1yV9hO0b8t5041K0g1+GCwH0GuOUzZ Cp1QB0Cx8eKtQXnilqhLNCkd6WPkE7k= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-138-l2T3D9uYM5mwyT9f8kttpQ-1; Thu, 04 Jul 2024 13:08:50 -0400 X-MC-Unique: l2T3D9uYM5mwyT9f8kttpQ-1 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-36710f4d5c9so579990f8f.3 for ; Thu, 04 Jul 2024 10:08:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112930; x=1720717730; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BQxAYuE6n+/DH+OguL+f/xlAy+kzOF6Lw0v+HCA+hEE=; b=il1+ka5DMVRoBK2ntUCI+z7CB4HI7ctniJwWUfhaqVc7m+HU0ykoXZpnrM73b2tIbF 8+cpb+U2lUkYOYplQmAxzhBX56ngfzE7v3HiQ8voHJ4bMyZWwvfro0BN82b/rdhHAyLN HVuiqQA6tvsmeiWtTc3OIDk4Ii/HJf1dlRvgagdsseR1lZf0ojvk26tS1zYMOc9M0ZiE O20HZHH7vVxDeRWlxjeO+QgIDFJJXh7GlcF9FbzLbgn0SUGiqHeZm/iWyfaIOJN0o9tn 6txSdeV/KoOm7Y9LsxbmGaJuC2FXXxSehr4tZ+hlTJQMsDe4Rp5afF3NxhJIaybrhoSb 0rPQ== X-Forwarded-Encrypted: i=1; AJvYcCVc48HBh8ZHsR6UeVV6r00f8tNzsc26P5LJBSWz0zpbPRpVId9nelyDVQB8KG3qjrWS2SXHC4U8GZcqZgKFjLiU6pPfUJwlPctiTmRj X-Gm-Message-State: AOJu0YzLMyHdFhxulBnnW1j1dRC8fl791MYZ4SdsRHLRTjwwXCs9tYrS TMQCWfpy6iVMld2OH5K/21bOY/yKjzwtF02lPqGFKrROozpHBZh9qRXoGaIOAr6xeU2jVc/5VQT ykVdxqnsJfK+kRNk8Fx6CZuVZE8gXYHqk2c5F6ac/QohFPUEW0Ob6tcjUMaML+g== X-Received: by 2002:a5d:4747:0:b0:367:2945:2bfa with SMTP id ffacd0b85a97d-3679dd63b64mr1747373f8f.52.1720112929686; Thu, 04 Jul 2024 10:08:49 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE9Oe8sBg1g3jKnRqqLj6OVJ/BT6D4UfPLf6dc0y8CTqERAnHlPHdZGQfd8llsP2TaSJQUN1Q== X-Received: by 2002:a5d:4747:0:b0:367:2945:2bfa with SMTP id ffacd0b85a97d-3679dd63b64mr1747351f8f.52.1720112929339; Thu, 04 Jul 2024 10:08:49 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3679dfae9easm1973191f8f.87.2024.07.04.10.08.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:48 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 09/20] rust: types: implement `Unique` Date: Thu, 4 Jul 2024 19:06:37 +0200 Message-ID: <20240704170738.3621-10-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement the `Unique` type as a prerequisite for `KBox` and `Kvec` introduced in subsequent patches. `Unique` serves as wrapper around a `NonNull`, but indicates that the possessor of this wrapper owns the referent. This type already exists in Rust's core library, but, unfortunately, is exposed as unstable API and hence shouldn't be used in the kernel. This implementation of `Unique` is almost identical, but mostly stripped down to the functionality we need for `KBox` and `KVec`. Additionally, all unstable features are removed and / or replaced by stable ones. Signed-off-by: Danilo Krummrich --- rust/kernel/types.rs | 176 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 2e7c9008621f..281327ea2932 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -409,3 +409,179 @@ pub enum Either { /// Constructs an instance of [`Either`] containing a value of type `R= `. Right(R), } + +/// A wrapper around a raw non-null `*mut T` that indicates that the posse= ssor +/// of this wrapper owns the referent. Useful for building abstractions li= ke +/// `Box`, `Vec`, `String`, and `HashMap`. +/// +/// Unlike `*mut T`, `Unique` behaves "as if" it were an instance of `T= `. +/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies +/// the kind of strong aliasing guarantees an instance of `T` can expect: +/// the referent of the pointer should not be modified without a unique pa= th to +/// its owning Unique. +/// +/// If you're uncertain of whether it's correct to use `Unique` for your p= urposes, +/// consider using `NonNull`, which has weaker semantics. +/// +/// Unlike `*mut T`, the pointer must always be non-null, even if the poin= ter +/// is never dereferenced. This is so that enums may use this forbidden va= lue +/// as a discriminant -- `Option>` has the same size as `Unique<= T>`. +/// However the pointer may still dangle if it isn't dereferenced. +/// +/// Unlike `*mut T`, `Unique` is covariant over `T`. This should always= be correct +/// for any type which upholds Unique's aliasing requirements. +#[repr(transparent)] +pub struct Unique { + pointer: NonNull, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-gener= ic-drop.md#phantom-data + _marker: PhantomData, +} + +/// `Unique` pointers are `Send` if `T` is `Send` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +unsafe impl Send for Unique {} + +/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +unsafe impl Sync for Unique {} + +impl Unique { + /// Creates a new `Unique` that is dangling, but well-aligned. + /// + /// This is useful for initializing types which lazily allocate, like + /// `Vec::new` does. + /// + /// Note that the pointer value may potentially represent a valid poin= ter to + /// a `T`, which means this must not be used as a "not yet initialized" + /// sentinel value. Types that lazily allocate must track initializati= on by + /// some other means. + #[must_use] + #[inline] + pub const fn dangling() -> Self { + Unique { + pointer: NonNull::dangling(), + _marker: PhantomData, + } + } +} + +impl Unique { + /// Creates a new `Unique`. + /// + /// # Safety + /// + /// `ptr` must be non-null. + #[inline] + pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { + // SAFETY: the caller must guarantee that `ptr` is non-null. + unsafe { + Unique { + pointer: NonNull::new_unchecked(ptr), + _marker: PhantomData, + } + } + } + + /// Creates a new `Unique` if `ptr` is non-null. + #[allow(clippy::manual_map)] + #[inline] + pub fn new(ptr: *mut T) -> Option { + if let Some(pointer) =3D NonNull::new(ptr) { + Some(Unique { + pointer, + _marker: PhantomData, + }) + } else { + None + } + } + + /// Acquires the underlying `*mut` pointer. + #[must_use =3D "`self` will be dropped if the result is not used"] + #[inline] + pub const fn as_ptr(self) -> *mut T { + self.pointer.as_ptr() + } + + /// Dereferences the content. + /// + /// The resulting lifetime is bound to self so this behaves "as if" + /// it were actually an instance of T that is getting borrowed. If a l= onger + /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. + /// + /// # Safety + /// + /// Safety requirements for this function are inherited from [NonNull:= :as_ref]. + /// + #[must_use] + #[inline] + pub const unsafe fn as_ref(&self) -> &T { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + unsafe { self.pointer.as_ref() } + } + + /// Mutably dereferences the content. + /// + /// The resulting lifetime is bound to self so this behaves "as if" + /// it were actually an instance of T that is getting borrowed. If a l= onger + /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. + /// + /// # Safety + /// + /// Safety requirements for this function are inherited from [NonNull:= :as_mut]. + #[must_use] + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a mutable reference. + unsafe { self.pointer.as_mut() } + } + + /// Casts to a pointer of another type. + #[must_use =3D "`self` will be dropped if the result is not used"] + #[inline] + pub fn cast(self) -> Unique { + Unique::from(self.pointer.cast()) + } +} + +impl Clone for Unique { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for Unique {} + +impl From<&mut T> for Unique { + /// Converts a `&mut T` to a `Unique`. + /// + /// This conversion is infallible since references cannot be null. + #[inline] + fn from(reference: &mut T) -> Self { + Self::from(NonNull::from(reference)) + } +} + +impl From> for Unique { + /// Converts a `NonNull` to a `Unique`. + /// + /// This conversion is infallible since `NonNull` cannot be null. + #[inline] + fn from(pointer: NonNull) -> Self { + Unique { + pointer, + _marker: PhantomData, + } + } +} --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 896D61C093F for ; Thu, 4 Jul 2024 17:08:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112940; cv=none; b=UcMVMS4NsPzh4p+lAwqkVeW6G8V6rnfpl4aawcug76D7hmBGYKYVo8iXR8fmvEKKqyW2wlunlJE2Jd4wyKhqeVTBRxharaOHtSxTzfKMfX6+AkKkLq9peB2HDS6P9KNofklQTsVbcm+jfDUVBoLpm6orTdjDpwzDWoW5RnI0Swk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112940; c=relaxed/simple; bh=McNG3UaBL1ItOv7lUZeO9yWA3Gg998SyrEB81aiN71Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VJmm7qHX9et+wSlJxX5HwKcOOvN0ltnXy4jOTMs8Blt0DG1BgvLww7weo+Pu6VWg/tiMvVyjw4gtuN6ewGIHwJfqLCaNcQ+657MNzXoa8owq9YXo8g77j5kwlWZUOIfyq7nhOlk/VHc8vBskJdw2YNAmCHx6PjxF8hWnM9rDL+M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=TStZ87yH; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TStZ87yH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112937; h=from:from: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; bh=mFTJALd1uc5PTttR7ib6e5/dU6QO/4gG6Rje8Pwa4QE=; b=TStZ87yHjsjO3oIrf+632P5dtsT9EmwjVIVYQSzXHZ21Nj2dOfMLlFhSefGYR605kgi/BV TsXmv3lmvhFb8vamJNBivW5S3yO4MxcXlTC84LL/BPBQHEayrFwUPWkRsWpoqMJGBQEjg+ zmwCDpleTNScO7Rt8vaFT02jpJGCAy4= Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-491-XerJYlkCO8yx4Nb7Dx3krA-1; Thu, 04 Jul 2024 13:08:56 -0400 X-MC-Unique: XerJYlkCO8yx4Nb7Dx3krA-1 Received: by mail-lj1-f200.google.com with SMTP id 38308e7fff4ca-2ee8f22ef7cso8485111fa.2 for ; Thu, 04 Jul 2024 10:08:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112935; x=1720717735; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mFTJALd1uc5PTttR7ib6e5/dU6QO/4gG6Rje8Pwa4QE=; b=XHpGuX3aw+JW9L2vS0IDWnpy+FwlnZXync8pLppeb6ge/7aqdfgq5bPVMSNTYdytKE aHTDRKX1vBuHngnmlozDSqKNTYotzxSRhm801KdBH5m1YRPhyCQ/7HLI76CT6TnZypDc fRBP35g5lmc/pNL11sfgp/sImXbThtHwlUxeQ3Ni9meodANcu3pr5jbkNxknzq57lQCh zfqrdxxh52SUS1ZcepZIbBZA7bCqMwR+8XXibVkNZI+C2yJuFDEOAOVjKT7MRjvUBRoD oYKfWGOi/fC4zU1Wgk/dH9Zs86RRT3bk8ArdXBvfXVe3kTlnYDe4aM0rAPJpZNcyc0eF PzLA== X-Forwarded-Encrypted: i=1; AJvYcCW6R/0xofzRDMOWpaYAVnGICxpl3U5Yy2h1qXnelQCx1GXWlhNETkYsJlLhhviKh9K15Jdy98agaBSBKpFfV/5xxtYU7mEx/6noOkOQ X-Gm-Message-State: AOJu0YzyNr25WSWR2VYN6kDATPDLa4V1/ZnZ+ZI8zCFY6SJQlwPhU+hd dyriLN5Tz/G6S6UtddxEYSsmNMvUDc9A4bKXD2PdW2qv5125WfTFPvwVoZxYEAX2rRFPo/BkF3b PdNMuy1QgqsmMYrIMsxjeSVM5mxXdSNXBzL2NrUles4DlgXTYa3hgP6ul579Pzw== X-Received: by 2002:a2e:be0e:0:b0:2ec:500c:b2e1 with SMTP id 38308e7fff4ca-2ee8ed3d2dbmr19484661fa.5.1720112934772; Thu, 04 Jul 2024 10:08:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHUtRKIuXsXzgO71ukyPTu4WnPhBOEE1r6DXR7c0mh98Dk6Ws6lY6iJdhRoHSBBCF6WbDIvwg== X-Received: by 2002:a2e:be0e:0:b0:2ec:500c:b2e1 with SMTP id 38308e7fff4ca-2ee8ed3d2dbmr19484331fa.5.1720112934307; Thu, 04 Jul 2024 10:08:54 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a21cba6sm31134675e9.22.2024.07.04.10.08.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:53 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 10/20] rust: alloc: implement `KBox` Date: Thu, 4 Jul 2024 19:06:38 +0200 Message-ID: <20240704170738.3621-11-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable `KBox` 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 `Box`, `KBox` 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 | 3 + rust/kernel/alloc/kbox.rs | 319 ++++++++++++++++++++++++++++++++++++++ rust/kernel/init.rs | 32 +++- rust/kernel/prelude.rs | 2 +- rust/kernel/types.rs | 23 +++ 5 files changed, 377 insertions(+), 2 deletions(-) create mode 100644 rust/kernel/alloc/kbox.rs diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 46ebdd059c92..ff90cefad0ea 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; =20 #[cfg(any(test, testlib))] @@ -13,6 +14,8 @@ #[cfg(any(test, testlib))] pub use self::allocator_test as allocator; =20 +pub use self::kbox::KBox; + /// 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..69976fd1d518 --- /dev/null +++ b/rust/kernel/alloc/kbox.rs @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Implementation of [`KBox`]. + +use super::{allocator::Kmalloc, AllocError, Allocator, Flags}; +use core::fmt; +use core::mem::ManuallyDrop; +use core::mem::MaybeUninit; +use core::ops::{Deref, DerefMut}; +use core::pin::Pin; +use core::ptr; +use core::result::Result; + +use crate::types::Unique; + +/// The kernel's `Box` type named [`KBox`]. +/// +/// `KBox` provides the simplest way to allocate memory for a generic type= with one of the kernel's +/// allocators, e.g. `Kmalloc`, `Vmalloc` or `KVmalloc`. +/// +/// For non-zero-sized values, a [`KBox`] will use the given allocator `A`= for its allocation. If +/// no specific `Allocator` is requested, [`KBox`] will default to `Kmallo= c`. +/// +/// It is valid to convert both ways between a [`KBox`] and a raw pointer = allocated with any +/// `Allocator`, given that the `Layout` used with the allocator is correc= t for the type. +/// +/// For zero-sized values the [`KBox`]' pointer must be `dangling_mut::= `; no memory is +/// allocated. +/// +/// So long as `T: Sized`, a `Box` is guaranteed to be represented as a= single pointer and is +/// also ABI-compatible with C pointers (i.e. the C type `T*`). +/// +/// # Invariants +/// +/// The [`KBox`]' pointer always properly aligned and either points to mem= ory allocated with `A` or, +/// for zero-sized types, is a dangling pointer. +/// +/// # Examples +/// +/// ``` +/// let b =3D KBox::new(24_u64, GFP_KERNEL)?; +/// +/// assert_eq!(*b, 24_u64); +/// +/// # Ok::<(), Error>(()) +/// ``` +/// +/// ``` +/// use kernel::alloc::allocator::KVmalloc; +/// +/// struct Huge([u8; 1 << 24]); +/// +/// assert!(KBox::::new_uninit_alloc(KVmalloc, GFP_KERNEL)= .is_ok()); +/// ``` +pub struct KBox(Unique, A); + +impl KBox +where + T: ?Sized, + A: Allocator, +{ + /// Constructs a `KBox` from a raw pointer. + /// + /// # Safety + /// + /// `raw` must point to valid memory, previously allocated with `A`, a= nd at least the size of + /// type `T`. + #[inline] + pub const unsafe fn from_raw_alloc(raw: *mut T, alloc: A) -> Self { + // SAFETY: Safe by the requirements of this function. + KBox(unsafe { Unique::new_unchecked(raw) }, alloc) + } + + /// Consumes the `KBox`, returning a wrapped raw pointer and the= allocator it was + /// allocated with. + /// + /// # Examples + /// + /// ``` + /// let x =3D KBox::new(24, GFP_KERNEL)?; + /// let (ptr, alloc) =3D KBox::into_raw_alloc(x); + /// let x =3D unsafe { KBox::from_raw_alloc(ptr, alloc) }; + /// + /// assert_eq!(*x, 24); + /// + /// # Ok::<(), Error>(()) + /// ``` + pub fn into_raw_alloc(self) -> (*mut T, A) { + let b =3D ManuallyDrop::new(self); + let alloc =3D unsafe { ptr::read(&b.1) }; + (b.0.as_ptr(), alloc) + } + + /// Consumes the `KBox`, returning a wrapped raw pointer. + #[inline] + pub fn into_raw(self) -> *mut T { + self.into_raw_alloc().0 + } + + /// Consumes and leaks the `KBox`, returning a mutable reference, &= 'a mut T. + #[inline] + pub fn leak<'a>(b: Self) -> &'a mut T + where + T: 'a, + { + // SAFETY: `KBox::into_raw` always returns a properly aligned and = dereferenceable pointer + // which points to an initialized instance of `T`. + unsafe { &mut *KBox::into_raw(b) } + } + + /// Converts a `KBox` into a `Pin>`. + #[inline] + pub fn into_pin(b: Self) -> Pin + where + A: 'static, + { + // SAFETY: It's not possible to move or replace the insides of a `= Pin>` when + // `T: !Unpin`, so it's safe to pin it directly without any additi= onal requirements. + unsafe { Pin::new_unchecked(b) } + } +} + +impl KBox, A> +where + A: Allocator, +{ + /// Converts to `KBox`. + /// + /// # Safety + /// + /// As with MaybeUninit::assume_init, it is up to the caller to guaran= tee that the value really + /// is in an initialized state. Calling this when the content is not y= et fully initialized + /// causes immediate undefined behavior. + pub unsafe fn assume_init(self) -> KBox { + let (raw, alloc) =3D KBox::into_raw_alloc(self); + // SAFETY: Reconstruct the `KBox, A>` as KBox= now that has been + // initialized. `raw` and `alloc` are safe by the invariants of `K= Box`. + unsafe { KBox::from_raw_alloc(raw as *mut T, alloc) } + } + + /// Writes the value and converts to `KBox`. + pub fn write(mut boxed: Self, value: T) -> KBox { + (*boxed).write(value); + // SAFETY: We've just initialized `boxed`'s value. + unsafe { boxed.assume_init() } + } +} + +impl KBox { + /// Allocates memory with `Kmalloc` and then places `x` into it. + /// + /// This doesn=E2=80=99t actually allocate if T is zero-sized. + pub fn new(x: T, flags: Flags) -> Result { + let b =3D Self::new_uninit(flags)?; + Ok(KBox::write(b, x)) + } + + /// Constructs a new `KBox` with uninitialized contents. + #[inline] + pub fn new_uninit(flags: Flags) -> Result>, AllocE= rror> { + Self::new_uninit_alloc(Kmalloc, flags) + } + + /// Constructs a new `Pin>`. If `T` does not implement [`Unpin= `], then `x` will be + /// pinned in memory and unable to be moved. + #[inline] + pub fn pin(x: T, flags: Flags) -> Result>, AllocError> { + Ok(KBox::new(x, flags)?.into()) + } +} + +impl KBox +where + T: ?Sized, +{ + /// Constructs a `KBox` from a raw pointer. + /// + /// # Safety + /// + /// `raw` must point to valid memory, previously allocated with the `K= malloc`, and at least the + /// size of type `T`. + #[inline] + pub const unsafe fn from_raw(raw: *mut T) -> Self { + // SAFETY: Validity of `raw` is guaranteed by the safety precondit= ions of this function. + KBox(unsafe { Unique::new_unchecked(raw) }, Kmalloc) + } +} + +impl KBox +where + A: Allocator, +{ + fn is_zst() -> bool { + core::mem::size_of::() =3D=3D 0 + } + + /// Allocates memory with the allocator `A` and then places `x` into i= t. + /// + /// This doesn=E2=80=99t actually allocate if T is zero-sized. + pub fn new_alloc(x: T, alloc: A, flags: Flags) -> Result { + let b =3D Self::new_uninit_alloc(alloc, flags)?; + Ok(KBox::write(b, x)) + } + + /// Constructs a new `KBox` with uninitialized contents. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::allocator::Kmalloc; + /// + /// let b =3D KBox::::new_uninit_alloc(Kmalloc, GFP_KERNEL)?; + /// let b =3D KBox::write(b, 24); + /// + /// assert_eq!(*b, 24_u64); + /// + /// # Ok::<(), Error>(()) + /// ``` + pub fn new_uninit_alloc(alloc: A, flags: Flags) -> Result, A>, AllocError> { + let ptr =3D if Self::is_zst() { + Unique::dangling() + } else { + let layout =3D core::alloc::Layout::new::>(); + let ptr =3D alloc.alloc(layout, flags)?; + + ptr.cast().into() + }; + + Ok(KBox(ptr, alloc)) + } + + /// Constructs a new `Pin>`. If `T` does not implement [`Un= pin`], then `x` will be + /// pinned in memory and unable to be moved. + #[inline] + pub fn pin_alloc(x: T, alloc: A, flags: Flags) -> Result>, AllocError> + where + A: 'static, + { + Ok(Self::new_alloc(x, alloc, flags)?.into()) + } +} + +impl From> for Pin> +where + T: ?Sized, + A: Allocator, + A: 'static, +{ + /// Converts a `KBox` into a `Pin>`. If `T` does not implem= ent [`Unpin`], then + /// `*boxed` will be pinned in memory and unable to be moved. + /// + /// This conversion does not allocate on the heap and happens in place. + /// + /// This is also available via [`KBox::into_pin`]. + /// + /// Constructing and pinning a `KBox` with >>::from= ([KBox::new]\(x)) + /// can also be written more concisely using [KBox::pin]\(x). + /// This `From` implementation is useful if you already have a `KBox`, or you are + /// constructing a (pinned) `KBox` in a different way than with [`KBox= ::new`]. + fn from(b: KBox) -> Self { + KBox::into_pin(b) + } +} + +impl Deref for KBox +where + T: ?Sized, + A: Allocator, +{ + type Target =3D T; + + fn deref(&self) -> &T { + // SAFETY: `self.0` is always properly aligned, dereferenceable an= d points to an initialized + // instance of `T`. + unsafe { self.0.as_ref() } + } +} + +impl DerefMut for KBox +where + T: ?Sized, + A: Allocator, +{ + fn deref_mut(&mut self) -> &mut T { + // SAFETY: `self.0` is always properly aligned, dereferenceable an= d points to an initialized + // instance of `T`. + unsafe { self.0.as_mut() } + } +} + +impl fmt::Debug for KBox +where + T: ?Sized + fmt::Debug, + A: Allocator, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl Drop for KBox +where + T: ?Sized, + A: Allocator, +{ + fn drop(&mut self) { + let ptr =3D self.0.as_ptr(); + + // SAFETY: We need to drop `self.0` in place, before we free the b= acking memory. + unsafe { core::ptr::drop_in_place(ptr) }; + + // SAFETY: `ptr` is always properly aligned, dereferenceable and p= oints to an initialized + // instance of `T`. + if unsafe { core::mem::size_of_val(&*ptr) } !=3D 0 { + // SAFETY: `ptr` was previously allocated with `self.1`. + unsafe { self.1.free(ptr.cast()) }; + } + } +} diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs index 68605b633e73..b34c8127b76d 100644 --- a/rust/kernel/init.rs +++ b/rust/kernel/init.rs @@ -211,7 +211,7 @@ //! [`pin_init!`]: crate::pin_init! =20 use crate::{ - alloc::{box_ext::BoxExt, AllocError, Flags}, + alloc::{box_ext::BoxExt, AllocError, Flags, KBox}, error::{self, Error}, sync::UniqueArc, types::{Opaque, ScopeGuard}, @@ -1183,6 +1183,36 @@ fn try_init(init: impl Init, flags: Flags) = -> Result } } =20 +impl InPlaceInit for KBox { + #[inline] + fn try_pin_init(init: impl PinInit, flags: Flags) -> Result, E> + where + E: From, + { + let mut this =3D KBox::<_>::new_uninit(flags)?; + let slot =3D this.as_mut_ptr(); + // SAFETY: When init errors/panics, slot will get deallocated but = not dropped, + // slot is valid and will not be moved, because we pin it later. + unsafe { init.__pinned_init(slot)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { this.assume_init() }.into()) + } + + #[inline] + fn try_init(init: impl Init, flags: Flags) -> Result + where + E: From, + { + let mut this =3D KBox::<_>::new_uninit(flags)?; + let slot =3D this.as_mut_ptr(); + // SAFETY: When init errors/panics, slot will get deallocated but = not dropped, + // slot is valid. + unsafe { init.__init(slot)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { this.assume_init() }) + } +} + impl InPlaceInit for UniqueArc { #[inline] fn try_pin_init(init: impl PinInit, flags: Flags) -> Result, E> diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index b37a0b3180fb..d75c14234133 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -14,7 +14,7 @@ #[doc(no_inline)] pub use core::pin::Pin; =20 -pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt}; +pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt, KBox}; =20 #[doc(no_inline)] pub use alloc::{boxed::Box, vec::Vec}; diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 281327ea2932..939ec27c584d 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -2,6 +2,7 @@ =20 //! Kernel types. =20 +use crate::alloc::KBox; use crate::init::{self, PinInit}; use alloc::boxed::Box; use core::{ @@ -89,6 +90,28 @@ unsafe fn from_foreign(ptr: *const core::ffi::c_void) ->= Self { } } =20 +impl ForeignOwnable for KBox { + type Borrowed<'a> =3D &'a T; + + fn into_foreign(self) -> *const core::ffi::c_void { + KBox::into_raw(self) as _ + } + + unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { + // SAFETY: The safety requirements for this function ensure that t= he object is still alive, + // so it is safe to dereference the raw pointer. + // The safety requirements of `from_foreign` also ensure that the = object remains alive for + // the lifetime of the returned value. + unsafe { &*ptr.cast() } + } + + unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { + // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous + // call to `Self::into_foreign`. + unsafe { KBox::from_raw(ptr as _) } + } +} + impl ForeignOwnable for () { type Borrowed<'a> =3D (); =20 --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5558B1C094E for ; Thu, 4 Jul 2024 17:09:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112944; cv=none; b=ovgkm+eI/CedKk6/uAYkmH7FU9m7Hcxq3+WNemaxhJ613Nv2KZpiBK8dOAp02v8IzE6Jc9aN3wpf3lGS6rNivxcgt0CikML1dfHP/wX8vGER0LDbperelQQRc387Lu6jYpQpGEOtgTH+a+UtF0wOHGdv5xTDh9eGPirDlePo4j4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112944; c=relaxed/simple; bh=QCzWpqZXmBuahkkczBh/8yo+05BdG/QuC+7cPjSB8w0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BQ/yj+NvVRAmFzsslaMEDaLyF8M9f2TMRQ/AZUfkPtCbIKhiuXOIY8zUaCdWZzMNaxzgjr+mUH5DQUrRmxYOo8nnEo0aykOMJGT/3meZNKiJBzBCYNnyJk1Mtt6XwYiW8HBvacWnRwhTqiBOisj/Z+fhmixNkwogWyfObApiYqc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=CiqQHgjI; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CiqQHgjI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g9s5070EIudwtdEBvneHUeqtniI+V0KQfF9cleWjjcI=; b=CiqQHgjII67dV5nRHVEd+kTA5G3Z7b6xgGyoLFR/E05eyTWlO/e3bhvbmxzH2X+DyPmHES TEBCitudzeWchl/7r0gwmQnnhDLQPeokqy5a5WiM14JqOlzVEdvwnnFlfezwvqAGIs/1lG h7AsSYkbj+E8Vb9QfeJRJPjpTd6Q84g= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-347-A_OXf53cO5aIQgy6pHtGXg-1; Thu, 04 Jul 2024 13:09:00 -0400 X-MC-Unique: A_OXf53cO5aIQgy6pHtGXg-1 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-367960f4673so965832f8f.1 for ; Thu, 04 Jul 2024 10:09:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112939; x=1720717739; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=g9s5070EIudwtdEBvneHUeqtniI+V0KQfF9cleWjjcI=; b=XM3CKDWNKJ/9jc+/3/2F1wcv+s+u8TRq0gzbPAYejo+mVzcX0SCq7zI7pQYnK5u5yp sS94061NKPcwpgEHb8511XzK3jp5ZSk33u4S2C/iPt8DOeXMtMJPhiDBqAgFnyX5AHsn sfVi4/c05XRyouaKxHwFn+wArZz+4oOJFiY4C83h23KaxAYK4ilMBHUvv+T88iyfUDvr 4LTcEIYxVB9KvtR3vgUQdbdtX4UjyFZELcQ1Rh+CEjrEnt9CWb8qkHF4Scj6BHxRxx0O Yu8RRjK7HQD2PHLq7Ft3WhKGQi3jH3yzkcgGGeTNQu+++VtOC07jCUCfUuQLkXDwZg4B 4sQw== X-Forwarded-Encrypted: i=1; AJvYcCVLy/h5pL/MYIxK6Bfl4bxGztvzMgIjfVUximBEMqKBT/rzIovXbuc43SkbrcaQM89Ml1R7iMYlhgpU35Zjq1f48fbRzQvgWGDqAx4A X-Gm-Message-State: AOJu0YyuNi2kzymzdllA6qiKZTGO1mHTE/7cS/embcBtbOiGzvCVvQa9 g6a2frSkLRgaBQjcc8r/gt1v5gDND0xSIiVZJv6alnhDqjzB8U1CfoY8YOoR/RosBcRXUwpNDaI Mi1sX/X67hsYMgQhvgPNLFUuHAk8VccIMay9FV/vpotN1P8B+Gg9uC/jqXIEiAg== X-Received: by 2002:a5d:59a6:0:b0:362:ff95:5697 with SMTP id ffacd0b85a97d-3679f75c493mr2832106f8f.28.1720112938772; Thu, 04 Jul 2024 10:08:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGvo+JVFuD9+NbLH1cJElJK3pJX6a+WqzYw5UAxXNq6UQpzUuKacAQGH0kimps9i1070QxGeg== X-Received: by 2002:a5d:59a6:0:b0:362:ff95:5697 with SMTP id ffacd0b85a97d-3679f75c493mr2832086f8f.28.1720112938332; Thu, 04 Jul 2024 10:08:58 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-36789d5ec1csm7097040f8f.37.2024.07.04.10.08.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:08:57 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 11/20] rust: treewide: switch to `KBox` Date: Thu, 4 Jul 2024 19:06:39 +0200 Message-ID: <20240704170738.3621-12-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that we got `KBox` in place, convert all existing `Box` users to `KBox`. Signed-off-by: Danilo Krummrich --- rust/kernel/init.rs | 62 ++++++++++++++++--------------- rust/kernel/init/__internal.rs | 2 +- rust/kernel/sync/arc.rs | 17 ++++----- rust/kernel/sync/condvar.rs | 5 ++- rust/kernel/sync/lock/mutex.rs | 3 +- rust/kernel/sync/lock/spinlock.rs | 3 +- rust/kernel/workqueue.rs | 22 +++++------ 7 files changed, 59 insertions(+), 55 deletions(-) diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs index b34c8127b76d..b386bafd5f95 100644 --- a/rust/kernel/init.rs +++ b/rust/kernel/init.rs @@ -13,7 +13,7 @@ //! To initialize a `struct` with an in-place constructor you will need tw= o things: //! - an in-place constructor, //! - a memory location that can hold your `struct` (this can be the [stac= k], an [`Arc`], -//! [`UniqueArc`], [`Box`] or any other smart pointer that impleme= nts [`InPlaceInit`]). +//! [`UniqueArc`], [`KBox`] or any other smart pointer that implem= ents [`InPlaceInit`]). //! //! To get an in-place constructor there are generally three options: //! - directly creating an in-place constructor using the [`pin_init!`] ma= cro, @@ -56,6 +56,7 @@ //! //! ```rust //! # #![allow(clippy::disallowed_names)] +//! # use kernel::alloc::KBox; //! # use kernel::sync::{new_mutex, Mutex}; //! # use core::pin::Pin; //! # #[pin_data] @@ -68,7 +69,7 @@ //! # a <- new_mutex!(42, "Foo::a"), //! # b: 24, //! # }); -//! let foo: Result>> =3D Box::pin_init(foo, GFP_KERNEL); +//! let foo: Result>> =3D KBox::pin_init(foo, GFP_KERNEL); //! ``` //! //! For more information see the [`pin_init!`] macro. @@ -88,19 +89,19 @@ //! //! ```rust //! # #![allow(clippy::disallowed_names)] -//! # use kernel::{sync::Mutex, new_mutex, init::PinInit, try_pin_init}; +//! # use kernel::{alloc::KBox, sync::Mutex, new_mutex, init::PinInit, try= _pin_init}; //! #[pin_data] //! struct DriverData { //! #[pin] //! status: Mutex, -//! buffer: Box<[u8; 1_000_000]>, +//! buffer: KBox<[u8; 1_000_000]>, //! } //! //! impl DriverData { //! fn new() -> impl PinInit { //! try_pin_init!(Self { //! status <- new_mutex!(0, "DriverData::status"), -//! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?, +//! buffer: KBox::init(kernel::init::zeroed(), GFP_KERNEL)?, //! }) //! } //! } @@ -292,12 +293,12 @@ macro_rules! stack_pin_init { /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mute= x, new_mutex}; /// # use macros::pin_data; -/// # use core::{alloc::AllocError, pin::Pin}; +/// # use core::{alloc::{AllocError, KBox}, pin::Pin}; /// #[pin_data] /// struct Foo { /// #[pin] /// a: Mutex, -/// b: Box, +/// b: KBox, /// } /// /// struct Bar { @@ -306,7 +307,7 @@ macro_rules! stack_pin_init { /// /// stack_try_pin_init!(let foo: Result, AllocError> =3D pin= _init!(Foo { /// a <- new_mutex!(42), -/// b: Box::new(Bar { +/// b: KBox::new(Bar { /// x: 64, /// }, GFP_KERNEL)?, /// })); @@ -318,12 +319,12 @@ macro_rules! stack_pin_init { /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mute= x, new_mutex}; /// # use macros::pin_data; -/// # use core::{alloc::AllocError, pin::Pin}; +/// # use core::{alloc::{AllocError, KBox}, pin::Pin}; /// #[pin_data] /// struct Foo { /// #[pin] /// a: Mutex, -/// b: Box, +/// b: KBox, /// } /// /// struct Bar { @@ -332,7 +333,7 @@ macro_rules! stack_pin_init { /// /// stack_try_pin_init!(let foo: Pin<&mut Foo> =3D? pin_init!(Foo { /// a <- new_mutex!(42), -/// b: Box::new(Bar { +/// b: KBox::new(Bar { /// x: 64, /// }, GFP_KERNEL)?, /// })); @@ -368,7 +369,7 @@ macro_rules! stack_try_pin_init { /// /// ```rust /// # #![allow(clippy::disallowed_names)] -/// # use kernel::{init, pin_init, macros::pin_data, init::*}; +/// # use kernel::{alloc::KBox, init, pin_init, macros::pin_data, init::*}; /// # use core::pin::Pin; /// #[pin_data] /// struct Foo { @@ -391,7 +392,7 @@ macro_rules! stack_try_pin_init { /// }, /// }); /// # initializer } -/// # Box::pin_init(demo(), GFP_KERNEL).unwrap(); +/// # KBox::pin_init(demo(), GFP_KERNEL).unwrap(); /// ``` /// /// Arbitrary Rust expressions can be used to set the value of a variable. @@ -440,7 +441,7 @@ macro_rules! stack_try_pin_init { /// /// ```rust /// # #![allow(clippy::disallowed_names)] -/// # use kernel::{init, pin_init, macros::pin_data, init::*}; +/// # use kernel::{alloc::KBox, init, pin_init, macros::pin_data, init::*}; /// # use core::pin::Pin; /// # #[pin_data] /// # struct Foo { @@ -461,7 +462,7 @@ macro_rules! stack_try_pin_init { /// # }) /// # } /// # } -/// let foo =3D Box::pin_init(Foo::new(), GFP_KERNEL); +/// let foo =3D KBox::pin_init(Foo::new(), GFP_KERNEL); /// ``` /// /// They can also easily embed it into their own `struct`s: @@ -590,10 +591,10 @@ macro_rules! pin_init { /// /// ```rust /// # #![feature(new_uninit)] -/// use kernel::{init::{self, PinInit}, error::Error}; +/// use kernel::{alloc::KBox, init::{self, PinInit}, error::Error}; /// #[pin_data] /// struct BigBuf { -/// big: Box<[u8; 1024 * 1024 * 1024]>, +/// big: KBox<[u8; 1024 * 1024 * 1024]>, /// small: [u8; 1024 * 1024], /// ptr: *mut u8, /// } @@ -601,7 +602,7 @@ macro_rules! pin_init { /// impl BigBuf { /// fn new() -> impl PinInit { /// try_pin_init!(Self { -/// big: Box::init(init::zeroed(), GFP_KERNEL)?, +/// big: KBox::init(init::zeroed(), GFP_KERNEL)?, /// small: [0; 1024 * 1024], /// ptr: core::ptr::null_mut(), /// }? Error) @@ -693,16 +694,16 @@ macro_rules! init { /// # Examples /// /// ```rust -/// use kernel::{init::{PinInit, zeroed}, error::Error}; +/// use kernel::{alloc::KBox, init::{PinInit, zeroed}, error::Error}; /// struct BigBuf { -/// big: Box<[u8; 1024 * 1024 * 1024]>, +/// big: KBox<[u8; 1024 * 1024 * 1024]>, /// small: [u8; 1024 * 1024], /// } /// /// impl BigBuf { /// fn new() -> impl Init { /// try_init!(Self { -/// big: Box::init(zeroed(), GFP_KERNEL)?, +/// big: KBox::init(zeroed(), GFP_KERNEL)?, /// small: [0; 1024 * 1024], /// }? Error) /// } @@ -745,8 +746,8 @@ macro_rules! try_init { /// A pin-initializer for the type `T`. /// /// To use this initializer, you will need a suitable memory location that= can hold a `T`. This can -/// be [`Box`], [`Arc`], [`UniqueArc`] or even the stack (see [`s= tack_pin_init!`]). Use the -/// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc`] = on this. +/// be [`KBox`], [`Arc`], [`UniqueArc`] or even the stack (see [`= stack_pin_init!`]). Use +/// the [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc`] on this. /// /// Also see the [module description](self). /// @@ -825,7 +826,7 @@ fn pin_chain(self, f: F) -> ChainPinInit } =20 /// An initializer returned by [`PinInit::pin_chain`]. -pub struct ChainPinInit(I, F, __internal::Invariant<(E= , Box)>); +pub struct ChainPinInit(I, F, __internal::Invariant<(E= , KBox)>); =20 // SAFETY: The `__pinned_init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -854,8 +855,8 @@ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(= ), E> { /// An initializer for `T`. /// /// To use this initializer, you will need a suitable memory location that= can hold a `T`. This can -/// be [`Box`], [`Arc`], [`UniqueArc`] or even the stack (see [`s= tack_pin_init!`]). Use the -/// [`InPlaceInit::init`] function of a smart pointer like [`Arc`] on t= his. Because +/// be [`KBox`], [`Arc`], [`UniqueArc`] or even the stack (see [`= stack_pin_init!`]). Use +/// the [`InPlaceInit::init`] function of a smart pointer like [`Arc`] = on this. Because /// [`PinInit`] is a super trait, you can use every function that ta= kes it as well. /// /// Also see the [module description](self). @@ -927,7 +928,7 @@ fn chain(self, f: F) -> ChainInit } =20 /// An initializer returned by [`Init::chain`]. -pub struct ChainInit(I, F, __internal::Invariant<(E, B= ox)>); +pub struct ChainInit(I, F, __internal::Invariant<(E, K= Box)>); =20 // SAFETY: The `__init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -1013,8 +1014,9 @@ pub fn uninit() -> impl Init, E>= { /// # Examples /// /// ```rust -/// use kernel::{error::Error, init::init_array_from_fn}; -/// let array: Box<[usize; 1_000]> =3D Box::init::(init_array_from_= fn(|i| i), GFP_KERNEL).unwrap(); +/// use kernel::{alloc::KBox, error::Error, init::init_array_from_fn}; +/// let array: KBox<[usize; 1_000]> =3D +/// KBox::init::(init_array_from_fn(|i| i), GFP_KERNEL).unwrap(= ); /// assert_eq!(array.len(), 1_000); /// ``` pub fn init_array_from_fn( @@ -1351,7 +1353,7 @@ macro_rules! impl_zeroable { // // In this case we are allowed to use `T: ?Sized`, since all zeros is = the `None` variant. {} Option>, - {} Option>, + {} Option>, =20 // SAFETY: `null` pointer is valid. // diff --git a/rust/kernel/init/__internal.rs b/rust/kernel/init/__internal.rs index db3372619ecd..dfb2204918c7 100644 --- a/rust/kernel/init/__internal.rs +++ b/rust/kernel/init/__internal.rs @@ -102,7 +102,7 @@ fn make_closure(self, f: F) -> F } } =20 -pub struct AllData(PhantomData) -> Box>); +pub struct AllData(PhantomData) -> KBox>); =20 impl Clone for AllData { fn clone(&self) -> Self { diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 3673496c2363..b5c84995d7d2 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -16,13 +16,12 @@ //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html =20 use crate::{ - alloc::{box_ext::BoxExt, AllocError, Flags}, + alloc::{AllocError, Flags, KBox}, error::{self, Error}, init::{self, InPlaceInit, Init, PinInit}, try_init, types::{ForeignOwnable, Opaque}, }; -use alloc::boxed::Box; use core::{ alloc::Layout, fmt, @@ -203,11 +202,11 @@ pub fn new(contents: T, flags: Flags) -> Result { data: contents, }; =20 - let inner =3D as BoxExt<_>>::new(value, flags)?; + let inner =3D KBox::new(value, flags)?; =20 // SAFETY: We just created `inner` with a reference count of 1, wh= ich is owned by the new // `Arc` object. - Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) + Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) }) } =20 /// Use the given initializer to in-place initialize a `T`. @@ -422,8 +421,8 @@ fn drop(&mut self) { if is_zero { // The count reached zero, we must free the memory. // - // SAFETY: The pointer was initialised from the result of `Box= ::leak`. - unsafe { drop(Box::from_raw(self.ptr.as_ptr())) }; + // SAFETY: The pointer was initialised from the result of `KBo= x::leak`. + unsafe { drop(KBox::from_raw(self.ptr.as_ptr())) }; } } } @@ -668,7 +667,7 @@ pub fn new(value: T, flags: Flags) -> Result { /// Tries to allocate a new [`UniqueArc`] instance whose contents are = not initialised yet. pub fn new_uninit(flags: Flags) -> Result>, A= llocError> { // INVARIANT: The refcount is initialised to a non-zero value. - let inner =3D Box::try_init::( + let inner =3D KBox::try_init::( try_init!(ArcInner { // SAFETY: There are no safety requirements for this FFI c= all. refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) = }), @@ -678,8 +677,8 @@ pub fn new_uninit(flags: Flags) -> Result>, AllocError> )?; Ok(UniqueArc { // INVARIANT: The newly-created object has a refcount of 1. - // SAFETY: The pointer from the `Box` is valid. - inner: unsafe { Arc::from_inner(Box::leak(inner).into()) }, + // SAFETY: The pointer from the `KBox` is valid. + inner: unsafe { Arc::from_inner(KBox::leak(inner).into()) }, }) } } diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs index 2b306afbe56d..700dcda58fb1 100644 --- a/rust/kernel/sync/condvar.rs +++ b/rust/kernel/sync/condvar.rs @@ -44,6 +44,7 @@ macro_rules! new_condvar { /// The following is an example of using a condvar with a mutex: /// /// ``` +/// use kernel::alloc::KBox; /// use kernel::sync::{new_condvar, new_mutex, CondVar, Mutex}; /// /// #[pin_data] @@ -70,8 +71,8 @@ macro_rules! new_condvar { /// } /// /// /// Allocates a new boxed `Example`. -/// fn new_example() -> Result>> { -/// Box::pin_init(pin_init!(Example { +/// fn new_example() -> Result>> { +/// KBox::pin_init(pin_init!(Example { /// value <- new_mutex!(0), /// value_changed <- new_condvar!(), /// }), GFP_KERNEL) diff --git a/rust/kernel/sync/lock/mutex.rs b/rust/kernel/sync/lock/mutex.rs index 30632070ee67..e19481cf0a2c 100644 --- a/rust/kernel/sync/lock/mutex.rs +++ b/rust/kernel/sync/lock/mutex.rs @@ -34,6 +34,7 @@ macro_rules! new_mutex { /// contains an inner struct (`Inner`) that is protected by a mutex. /// /// ``` +/// use kernel::alloc::KBox; /// use kernel::sync::{new_mutex, Mutex}; /// /// struct Inner { @@ -58,7 +59,7 @@ macro_rules! new_mutex { /// } /// /// // Allocate a boxed `Example`. -/// let e =3D Box::pin_init(Example::new(), GFP_KERNEL)?; +/// let e =3D KBox::pin_init(Example::new(), GFP_KERNEL)?; /// assert_eq!(e.c, 10); /// assert_eq!(e.d.lock().a, 20); /// assert_eq!(e.d.lock().b, 30); diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spin= lock.rs index ea5c5bc1ce12..dfb74dfefafe 100644 --- a/rust/kernel/sync/lock/spinlock.rs +++ b/rust/kernel/sync/lock/spinlock.rs @@ -32,6 +32,7 @@ macro_rules! new_spinlock { /// contains an inner struct (`Inner`) that is protected by a spinlock. /// /// ``` +/// use kernel::alloc::KBox; /// use kernel::sync::{new_spinlock, SpinLock}; /// /// struct Inner { @@ -56,7 +57,7 @@ macro_rules! new_spinlock { /// } /// /// // Allocate a boxed `Example`. -/// let e =3D Box::pin_init(Example::new(), GFP_KERNEL)?; +/// let e =3D KBox::pin_init(Example::new(), GFP_KERNEL)?; /// assert_eq!(e.c, 10); /// assert_eq!(e.d.lock().a, 20); /// assert_eq!(e.d.lock().b, 30); diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 1cec63a2aea8..e1a1606267ed 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -130,7 +130,7 @@ //! //! C header: [`include/linux/workqueue.h`](srctree/include/linux/workqueu= e.h) =20 -use crate::alloc::{AllocError, Flags}; +use crate::alloc::{AllocError, Flags, KBox}; use crate::{prelude::*, sync::Arc, sync::LockClassKey, types::Opaque}; use core::marker::PhantomData; =20 @@ -216,7 +216,7 @@ pub fn try_spawn( func: Some(func), }); =20 - self.enqueue(Box::pin_init(init, flags).map_err(|_| AllocError)?); + self.enqueue(KBox::pin_init(init, flags).map_err(|_| AllocError)?); Ok(()) } } @@ -239,9 +239,9 @@ fn project(self: Pin<&mut Self>) -> &mut Option { } =20 impl WorkItem for ClosureWork { - type Pointer =3D Pin>; + type Pointer =3D Pin>; =20 - fn run(mut this: Pin>) { + fn run(mut this: Pin>) { if let Some(func) =3D this.as_mut().project().take() { (func)() } @@ -297,7 +297,7 @@ unsafe fn __enqueue(self, queue_work_on: F) -> Self:= :EnqueueOutput =20 /// Defines the method that should be called directly when a work item is = executed. /// -/// This trait is implemented by `Pin>` and [`Arc`], and is main= ly intended to be +/// This trait is implemented by `Pin>` and [`Arc`], and is mai= nly intended to be /// implemented for smart pointer types. For your own structs, you would i= mplement [`WorkItem`] /// instead. The [`run`] method on this trait will usually just perform th= e appropriate /// `container_of` translation and then call into the [`run`][WorkItem::ru= n] method from the @@ -329,7 +329,7 @@ pub unsafe trait WorkItemPointer: RawWor= kItem { /// This trait is used when the `work_struct` field is defined using the [= `Work`] helper. pub trait WorkItem { /// The pointer type that this struct is wrapped in. This will typical= ly be `Arc` or - /// `Pin>`. + /// `Pin>`. type Pointer: WorkItemPointer; =20 /// The method that should be called when this work item is executed. @@ -563,7 +563,7 @@ unsafe fn __enqueue(self, queue_work_on: F) -> Self:= :EnqueueOutput } } =20 -unsafe impl WorkItemPointer for Pin> +unsafe impl WorkItemPointer for Pin> where T: WorkItem, T: HasWork, @@ -574,7 +574,7 @@ unsafe impl WorkItemPointer for P= in> // SAFETY: This computes the pointer that `__enqueue` got from `Ar= c::into_raw`. let ptr =3D unsafe { T::work_container_of(ptr) }; // SAFETY: This pointer comes from `Arc::into_raw` and we've been = given back ownership. - let boxed =3D unsafe { Box::from_raw(ptr) }; + let boxed =3D unsafe { KBox::from_raw(ptr) }; // SAFETY: The box was already pinned when it was enqueued. let pinned =3D unsafe { Pin::new_unchecked(boxed) }; =20 @@ -582,7 +582,7 @@ unsafe impl WorkItemPointer for P= in> } } =20 -unsafe impl RawWorkItem for Pin> +unsafe impl RawWorkItem for Pin> where T: WorkItem, T: HasWork, @@ -596,9 +596,9 @@ unsafe fn __enqueue(self, queue_work_on: F) -> Self:= :EnqueueOutput // SAFETY: We're not going to move `self` or any of its fields, so= its okay to temporarily // remove the `Pin` wrapper. let boxed =3D unsafe { Pin::into_inner_unchecked(self) }; - let ptr =3D Box::into_raw(boxed); + let ptr =3D KBox::into_raw(boxed); =20 - // SAFETY: Pointers into a `Box` point at a valid value. + // SAFETY: Pointers into a `KBox` point at a valid value. let work_ptr =3D unsafe { T::raw_get_work(ptr) }; // SAFETY: `raw_get_work` returns a pointer to a valid value. let work_ptr =3D unsafe { Work::raw_get(work_ptr) }; --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC9D51C2DCA for ; Thu, 4 Jul 2024 17:09:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112948; cv=none; b=FLNJAN66jeE3XKgj1vD2SMoo7KM8tyxWrMT8qlszNX8tmikwwbtICaAD0HBJWHHhS1ku/Dlj+cDGOAESMd8hZjrY1FjmThJAXkm8GZpyDXBnxq+0tXVbuiZ2A2vxoculJdmwSbANcnfaqaBaQNjlZNy62+qQCYCMxlOY8gfZ348= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112948; c=relaxed/simple; bh=o87Q6nrhXq+2epNBXh/xEE5xjiGWYWfou9Wo5ZW6Mxg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Oa7q3Jpi0Iq1xpR61e+xefshYQ++2Wk+fbpt09b9OCE3tAYlgeKaJOsSUf0eYehFvVh4u8np4oWazS2zGYuunY6lCsMtxxkqQIhuhGWb0QGnbK08XDeQNYaK/ctNktOwpr4a4xsrXCZJB2WBc2o63CyUvXU37isSki84MsUYDGY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Wn2diid4; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Wn2diid4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IsEZYPUnJUrFTc5sYGJG2HQ1b8hAp+MrWs9/jDi7WD8=; b=Wn2diid4bURJYZQ/P6v0k3mI9lB76ktRVaUDv563FXrBwcZUdyMq0pPQd8lfor4dv7guxw 2QF3twiyhUR3bZ/ke13x+/J2xQEgpjCAh/qDcnf/sqEP4Dnnl9t+DneH6y4n5wRhsyio9h bYsDji1yvRMzph0u3tHLAvligC/xaHc= Received: from mail-lf1-f69.google.com (mail-lf1-f69.google.com [209.85.167.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-150-4I8d-4W6PAaym0InC0Ihfw-1; Thu, 04 Jul 2024 13:09:04 -0400 X-MC-Unique: 4I8d-4W6PAaym0InC0Ihfw-1 Received: by mail-lf1-f69.google.com with SMTP id 2adb3069b0e04-52e982ace13so914596e87.0 for ; Thu, 04 Jul 2024 10:09:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112943; x=1720717743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IsEZYPUnJUrFTc5sYGJG2HQ1b8hAp+MrWs9/jDi7WD8=; b=dQ9EMmVyd5SoPu+nAdaHgvXbObag3taKXw3mwHu0slW0nLRu63T5fSJduue95ffCTM ZtvfdD1UfX+WRMp46j04tz2nEOovGisdQbXjF5J2t2W8jSU5pInGKt3Zj2i52IkygFpG g3PXsabL34qX5q/POnUh3SPo3kKL4PgCxHi/tmTzGyJAzL9NDkQuFlJrVQEqnGxzbClS juyIJVFC5nDMuVSVhgnT/kpschobxO5ZEdoORrp4wWVrxW2TqlVt35e4fIV8bicQKJ3l Z2c9pRwmDHgMmzm/wG2cbFACGA7uy/BVt46Teu9muyAZYXanxEdEoUOPW3w7sWrNLP8v 8gJw== X-Forwarded-Encrypted: i=1; AJvYcCVVyNNKUoyTcIn4RwC5i8aJcxQT68raqChYIoThoZUowTLwCmlMycazi5dvpfwNjWD+h05+xQDghANv4ykxROHMffx4KfI+WTafpuFS X-Gm-Message-State: AOJu0YzoIZjwY2NfLc8BHzhOSc9KvKgWBglualgo271fhsKYqrUKxipa U4LXFko75eVR+LlYZlJoreO5jPrLbScn3m9zCM8VXr/pLjIBu6Rou5/uVgihLnUSIEvFp0Hvun+ Djp6qG8Z1AJewb+CJvFkz62YgbYui8oDExbEjuW7fBcnK4+8BNzqzqx3uKb/Dr/oFTxsv3Q== X-Received: by 2002:a19:7501:0:b0:52c:c9cd:ebc3 with SMTP id 2adb3069b0e04-52ea06e3e43mr1409953e87.63.1720112942716; Thu, 04 Jul 2024 10:09:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHHEaZYFSL8J5jp11qG3WtnRhMrCxosPHJENTXOj/vhYDA1OWkwhTMXpmw5imfcG5/3gGCmgw== X-Received: by 2002:a19:7501:0:b0:52c:c9cd:ebc3 with SMTP id 2adb3069b0e04-52ea06e3e43mr1409919e87.63.1720112942319; Thu, 04 Jul 2024 10:09:02 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367a5a31a1asm301302f8f.7.2024.07.04.10.09.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:01 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 12/20] rust: alloc: remove `BoxExt` extension Date: Thu, 4 Jul 2024 19:06:40 +0200 Message-ID: <20240704170738.3621-13-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that all existing `Box` users were moved to `KBox`, remove the `BoxExt` extension. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 1 - rust/kernel/alloc/box_ext.rs | 51 ------------------------------------ rust/kernel/init.rs | 34 +----------------------- rust/kernel/lib.rs | 1 - rust/kernel/prelude.rs | 4 +-- rust/kernel/types.rs | 23 ---------------- 6 files changed, 3 insertions(+), 111 deletions(-) delete mode 100644 rust/kernel/alloc/box_ext.rs diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index ff90cefad0ea..882a65212653 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -4,7 +4,6 @@ =20 #[cfg(not(any(test, testlib)))] pub mod allocator; -pub mod box_ext; pub mod kbox; pub mod vec_ext; =20 diff --git a/rust/kernel/alloc/box_ext.rs b/rust/kernel/alloc/box_ext.rs deleted file mode 100644 index 1aeae02c147e..000000000000 --- a/rust/kernel/alloc/box_ext.rs +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -//! Extensions to [`Box`] for fallible allocations. - -use super::{AllocError, Flags}; -use alloc::boxed::Box; -use core::mem::MaybeUninit; - -/// Extensions to [`Box`]. -pub trait BoxExt: Sized { - /// Allocates a new box. - /// - /// The allocation may fail, in which case an error is returned. - fn new(x: T, flags: Flags) -> Result; - - /// Allocates a new uninitialised box. - /// - /// The allocation may fail, in which case an error is returned. - fn new_uninit(flags: Flags) -> Result>, AllocError>; -} - -impl BoxExt for Box { - fn new(x: T, flags: Flags) -> Result { - let b =3D >::new_uninit(flags)?; - Ok(Box::write(b, x)) - } - - #[cfg(any(test, testlib))] - fn new_uninit(_flags: Flags) -> Result>, AllocError= > { - Ok(Box::new_uninit()) - } - - #[cfg(not(any(test, testlib)))] - fn new_uninit(flags: Flags) -> Result>, AllocError>= { - let ptr =3D if core::mem::size_of::>() =3D=3D 0 { - core::ptr::NonNull::dangling() - } else { - let alloc: &dyn super::Allocator =3D &super::allocator::Kmallo= c; - let layout =3D core::alloc::Layout::new::>(); - - // SAFETY: Memory is being allocated (first arg is null). The = only other source of - // safety issues is sleeping on atomic context, which is addre= ssed by klint. Lastly, - // the type is not a SZT (checked above). - alloc.alloc(layout, flags)?.cast() - }; - - // SAFETY: For non-zero-sized types, we allocate above using the g= lobal allocator. For - // zero-sized types, we use `NonNull::dangling`. - Ok(unsafe { Box::from_raw(ptr.as_ptr()) }) - } -} diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs index b386bafd5f95..f59f502c3e0b 100644 --- a/rust/kernel/init.rs +++ b/rust/kernel/init.rs @@ -212,12 +212,11 @@ //! [`pin_init!`]: crate::pin_init! =20 use crate::{ - alloc::{box_ext::BoxExt, AllocError, Flags, KBox}, + alloc::{AllocError, Flags, KBox}, error::{self, Error}, sync::UniqueArc, types::{Opaque, ScopeGuard}, }; -use alloc::boxed::Box; use core::{ cell::UnsafeCell, convert::Infallible, @@ -590,7 +589,6 @@ macro_rules! pin_init { /// # Examples /// /// ```rust -/// # #![feature(new_uninit)] /// use kernel::{alloc::KBox, init::{self, PinInit}, error::Error}; /// #[pin_data] /// struct BigBuf { @@ -1155,36 +1153,6 @@ fn init(init: impl Init, flags: Flags) -> e= rror::Result } } =20 -impl InPlaceInit for Box { - #[inline] - fn try_pin_init(init: impl PinInit, flags: Flags) -> Result, E> - where - E: From, - { - let mut this =3D as BoxExt<_>>::new_uninit(flags)?; - let slot =3D this.as_mut_ptr(); - // SAFETY: When init errors/panics, slot will get deallocated but = not dropped, - // slot is valid and will not be moved, because we pin it later. - unsafe { init.__pinned_init(slot)? }; - // SAFETY: All fields have been initialized. - Ok(unsafe { this.assume_init() }.into()) - } - - #[inline] - fn try_init(init: impl Init, flags: Flags) -> Result - where - E: From, - { - let mut this =3D as BoxExt<_>>::new_uninit(flags)?; - let slot =3D this.as_mut_ptr(); - // SAFETY: When init errors/panics, slot will get deallocated but = not dropped, - // slot is valid. - unsafe { init.__init(slot)? }; - // SAFETY: All fields have been initialized. - Ok(unsafe { this.assume_init() }) - } -} - impl InPlaceInit for KBox { #[inline] fn try_pin_init(init: impl PinInit, flags: Flags) -> Result, E> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index fbd91a48ff8b..f119bbde955b 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -14,7 +14,6 @@ #![no_std] #![feature(coerce_unsized)] #![feature(dispatch_from_dyn)] -#![feature(new_uninit)] #![feature(receiver_trait)] #![feature(unsize)] =20 diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index d75c14234133..20112233d750 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -14,10 +14,10 @@ #[doc(no_inline)] pub use core::pin::Pin; =20 -pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt, KBox}; +pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox}; =20 #[doc(no_inline)] -pub use alloc::{boxed::Box, vec::Vec}; +pub use alloc::vec::Vec; =20 #[doc(no_inline)] pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable}; diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 939ec27c584d..0b2a3ce538a6 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -4,7 +4,6 @@ =20 use crate::alloc::KBox; use crate::init::{self, PinInit}; -use alloc::boxed::Box; use core::{ cell::UnsafeCell, marker::{PhantomData, PhantomPinned}, @@ -68,28 +67,6 @@ unsafe fn try_from_foreign(ptr: *const core::ffi::c_void= ) -> Option { } } =20 -impl ForeignOwnable for Box { - type Borrowed<'a> =3D &'a T; - - fn into_foreign(self) -> *const core::ffi::c_void { - Box::into_raw(self) as _ - } - - unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { - // SAFETY: The safety requirements for this function ensure that t= he object is still alive, - // so it is safe to dereference the raw pointer. - // The safety requirements of `from_foreign` also ensure that the = object remains alive for - // the lifetime of the returned value. - unsafe { &*ptr.cast() } - } - - unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { - // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous - // call to `Self::into_foreign`. - unsafe { Box::from_raw(ptr as _) } - } -} - impl ForeignOwnable for KBox { type Borrowed<'a> =3D &'a T; =20 --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 17E0F1B3F08 for ; Thu, 4 Jul 2024 17:09:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112957; cv=none; b=lNtaJ/PBlj2o6STP4s0yUgFUk503Uy/CMLkl1Ki7NrYGxqHiPkaT6oZdrtWpg0hwKhh3B4YvspfN6Xl+lONSc4j1k7b2l7ngil+A4aWX/B5QDpPSyiACfjkZ0A8qhwfnakBVCQdbyN9OV0tJBnwL2wcw6IpZZ6jMErP2zDrJZJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112957; c=relaxed/simple; bh=oZ+Kffa+ZusYQvmQFj/KKP+hW54mb7jaO1sWCol6BqY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uS+VqeokTKBRjw7enqTNC7pT5jTAqq6VZ2LMl3ov0elUHYQkxEX9zlU+2CjbWJPmAXkraJioDo37d9S/bkqPY7JKh0tH8u5ChfL2DAwmxtP7y5+gd4UChhtzxcBzulK9svp23+h+bzT8E5/rzA0fBdGspbr9TwjWMdMb3n+P2y4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=jSbDeIKS; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="jSbDeIKS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112953; h=from:from: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; bh=h3os753SbfqzKgGGDKsUwcQmZvaE0TXjXE9ormHju54=; b=jSbDeIKSuympk+PcpSL/IQbxeWotEWwXMgaMEpnz4jvJNPD1J/fgLWl1gPdUYqoJl1yKV4 psJ0Bud8LRUvTIGPZRtFtI+alZWqvhPTPHgst3wYuOk3BX4XaDtZUcW0WizmSuG7oA27fP +R0icC9BAS9kOOFWS9IP1sHqZfCXkDg= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-2-BF6tnMVuPdyONSswNLEF3A-1; Thu, 04 Jul 2024 13:09:09 -0400 X-MC-Unique: BF6tnMVuPdyONSswNLEF3A-1 Received: by mail-lj1-f197.google.com with SMTP id 38308e7fff4ca-2ee90290a7aso10568511fa.3 for ; Thu, 04 Jul 2024 10:09:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112947; x=1720717747; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h3os753SbfqzKgGGDKsUwcQmZvaE0TXjXE9ormHju54=; b=clvSmSbPEfsdAMW0TtDp0ywGY6NCfoLuHf/kP+4sbLQkiSNrS25+ZwqYAhoCnS7lA+ pAy1SC90LApOzpX5U86/fdXX/5Syvot4g8QYvVzwzw0f0eq3pAGT0L6cs1WymeKHpvTp qqTII5a4n2X01fdrhWnAXdiE0EI3GPIJYKoMd25NfUaGx5ufkYgCXdNtvkh4AZ6i0Wg3 nUiYzpWmmNAD6mBaXQThzgKLJg/1d6RBi2bEMS6z87MMuXEL/eyQSRKfUlfZyVEFeiUy 0PYSSgaqaNsCxroymb3oKg9+PIYMeqwWCKlyl/P6cwSyF08LXFIgppE+K4tjtQkW4eso qt5w== X-Forwarded-Encrypted: i=1; AJvYcCWLYm7IqfvWg1poMUpAocwt/K2O3fHLhkOENoA2C9jUO0fad4RT5KiNmGtJKF/YJ2WTRxqHc3EenO8nqbdscj4NbaevLmmxFcKRLTSt X-Gm-Message-State: AOJu0YzOTQwbCZwWwuQMb2Shxww/0183iWKgsbBm5K3FFrM8QyCK/AMX E9lFKHWy6/tvT2w9suXMahavg6wCd3By/cyfFqnh5FeQyIkquCPcWRbn5PO82iQvqXZtAiKb8Dz 0y9mY3a6NnHSW/+kBwfTZJYonCVt8d2bLRkeSZ4hhaE3LcHgs6jryfEvIfnbVLA== X-Received: by 2002:a05:651c:2209:b0:2ec:5f85:61c0 with SMTP id 38308e7fff4ca-2ee8ee212b1mr23322651fa.48.1720112947040; Thu, 04 Jul 2024 10:09:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG9Lf70Kg2a/722PZCeDhipNzzQHZf+40ZKS8SuAc7xOSzXMTQ+h2nQIGMDULoUis5F7hbyyA== X-Received: by 2002:a05:651c:2209:b0:2ec:5f85:61c0 with SMTP id 38308e7fff4ca-2ee8ee212b1mr23322221fa.48.1720112946421; Thu, 04 Jul 2024 10:09:06 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3675a103d00sm18993136f8f.99.2024.07.04.10.09.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:05 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 13/20] rust: alloc: implement `KVec` Date: Thu, 4 Jul 2024 19:06:41 +0200 Message-ID: <20240704170738.3621-14-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable `KVec` provides a contiguous growable array type (such as `Vec`) with contents allocated with the kernel's allocators (e.g. `Kmalloc`, `Vmalloc` or `KVmalloc`). In contrast to `Vec`, `KVec` 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 | 2 + rust/kernel/alloc/kbox.rs | 16 +- rust/kernel/alloc/kvec.rs | 605 ++++++++++++++++++++++++++++++++++++++ rust/kernel/prelude.rs | 2 +- 4 files changed, 623 insertions(+), 2 deletions(-) create mode 100644 rust/kernel/alloc/kvec.rs diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 882a65212653..3a0195d23bb4 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 kbox; +pub mod kvec; pub mod vec_ext; =20 #[cfg(any(test, testlib))] @@ -14,6 +15,7 @@ pub use self::allocator_test as allocator; =20 pub use self::kbox::KBox; +pub use self::kvec::KVec; =20 /// Indicates an allocation error. #[derive(Copy, Clone, PartialEq, Eq, Debug)] diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 69976fd1d518..3cb2d12f7c39 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -2,7 +2,7 @@ =20 //! Implementation of [`KBox`]. =20 -use super::{allocator::Kmalloc, AllocError, Allocator, Flags}; +use super::{allocator::Kmalloc, AllocError, Allocator, Flags, KVec}; use core::fmt; use core::mem::ManuallyDrop; use core::mem::MaybeUninit; @@ -120,6 +120,20 @@ pub fn into_pin(b: Self) -> Pin } } =20 +impl KBox<[T; N], A> +where + A: Allocator, +{ + /// Convert a `KBox<[T], A>` to a `KVec`. + pub fn into_vec(self) -> KVec { + let len =3D self.len(); + unsafe { + let (ptr, alloc) =3D self.into_raw_alloc(); + KVec::from_raw_parts_alloc(ptr as _, len, len, alloc) + } + } +} + impl KBox, A> where A: Allocator, diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs new file mode 100644 index 000000000000..7ec898657832 --- /dev/null +++ b/rust/kernel/alloc/kvec.rs @@ -0,0 +1,605 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Implementation of [`KVec`]. + +use super::{allocator::Kmalloc, AllocError, Allocator, Flags}; +use crate::types::Unique; +use core::{ + fmt, + mem::{ManuallyDrop, MaybeUninit}, + ops::Deref, + ops::DerefMut, + ops::Index, + ops::IndexMut, + ptr, slice, + slice::SliceIndex, +}; + +/// Create a [`KVec`] containing the arguments. +/// +/// # Examples +/// +/// ``` +/// use kernel::alloc::{flags::*, KVec}; +/// +/// let mut v =3D kernel::kvec![]; +/// v.push(1, GFP_KERNEL).unwrap(); +/// assert_eq!(v, [1]); +/// +/// let mut v =3D kernel::kvec![1; 3]?; +/// v.push(4, GFP_KERNEL).unwrap(); +/// assert_eq!(v, [1, 1, 1, 4]); +/// +/// let mut v =3D kernel::kvec![1, 2, 3]?; +/// v.push(4, GFP_KERNEL).unwrap(); +/// assert_eq!(v, [1, 2, 3, 4]); +/// +/// # Ok::<(), Error>(()) +/// ``` +#[macro_export] +macro_rules! kvec { + () =3D> ( + { + $crate::alloc::KVec::new() + } + ); + ($elem:expr; $n:expr) =3D> ( + { + $crate::alloc::KVec::from_elem( + $elem, $n, + $crate::alloc::allocator::Kmalloc, + GFP_KERNEL + ) + } + ); + ($($x:expr),+ $(,)?) =3D> ( + { + match $crate::alloc::KBox::new([$($x),+], GFP_KERNEL) { + Ok(b) =3D> Ok($crate::alloc::KBox::into_vec(b)), + Err(e) =3D> Err(e), + } + } + ); +} + +/// The kernel's `Vec` type named [`KVec`]. +/// +/// A contiguous growable array type with contents allocated with the kern= el's allocators (e.g. +/// `Kmalloc`, `Vmalloc` or `KVmalloc`, written `KVec`. +/// +/// For non-zero-sized values, a [`KVec`] will use the given allocator `A`= for its allocation. If +/// no specific `Allocator` is requested, [`KVec`] will default to `Kmallo= c`. +/// +/// For zero-sized types the [`KVec`]'s pointer must be `dangling_mut::= `; no memory is allocated. +/// +/// Generally, [`KVec`] consists of a pointer that represents the vector's= backing buffer, the +/// capacity of the vector (the number of elements that currently fit into= the vector), it's length +/// (the number of elements that are currently stored in the vector) and t= he `Allocator` used to +/// allocate (and free) the backing buffer. +/// +/// A [`KVec`] can be deconstructed into and (re-)constructed from it's pr= eviously named raw parts +/// and manually modified. +/// +/// [`KVec`]'s backing buffer gets, if required, automatically increased (= re-allocated) when +/// elements are added to the vector. +/// +/// # Invariants +/// +/// The [`KVec`] backing buffer's pointer always properly aligned and eith= er points to memory +/// allocated with `A` or, for zero-sized types, is a dangling pointer. +/// +/// The length of the vector always represents the exact number of element= s stored in the vector. +/// +/// The capacity of the vector always represents the absolute number of el= ements that can be stored +/// within the vector without re-allocation. However, it is legal for the = backing buffer to be +/// larger than `size_of` times the capacity. +/// +/// The `Allocator` of the vector is the exact allocator the backing buffe= r was allocated with (and +/// must be freed with). +pub struct KVec { + ptr: Unique, + /// Never used for ZSTs; it's `capacity()`'s responsibility to return = usize::MAX in that case. + /// + /// # Safety + /// + /// `cap` must be in the `0..=3Disize::MAX` range. + cap: usize, + len: usize, + alloc: A, +} + +impl KVec { + /// Create a new empty `KVec` with no memory allocated yet. + #[inline] + pub const fn new() -> Self { + Self::new_alloc(Kmalloc) + } + + /// Creates a new [`KVec`] instance with at least the given capacity. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{flags::*, KVec}; + /// + /// let v =3D KVec::::with_capacity(20, GFP_KERNEL)?; + /// + /// assert!(v.capacity() >=3D 20); + /// # Ok::<(), Error>(()) + /// ``` + #[inline] + pub fn with_capacity(capacity: usize, flags: Flags) -> Result { + Self::with_capacity_alloc(capacity, Kmalloc, flags) + } +} + +impl KVec +where + A: Allocator, +{ + #[inline] + fn is_zst() -> bool { + core::mem::size_of::() =3D=3D 0 + } + + fn buffer_size(capacity: usize) -> Result { + if Self::is_zst() { + Ok(0) + } else { + capacity + .checked_mul(core::mem::size_of::()) + .ok_or(AllocError) + } + } + + /// Returns a reference to the underlying allocator. + #[inline] + pub fn allocator(&self) -> &A { + &self.alloc + } + + /// Returns the total number of elements the vector can hold without + /// reallocating. + pub fn capacity(&self) -> usize { + if Self::is_zst() { + usize::MAX + } else { + self.cap + } + } + + /// Returns the number of elements in the vector, also referred to + /// as its 'length'. + #[inline] + pub fn len(&self) -> usize { + self.len + } + + /// Forces the length of the vector to new_len. + /// + /// # Safety + /// + /// - `new_len` must be less than or equal to [`Self::capacity()`]. + /// - The elements at `old_len..new_len` must be initialized. + #[inline] + pub unsafe fn set_len(&mut self, new_len: usize) { + self.len =3D new_len; + } + + /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. + #[inline] + pub fn as_slice(&self) -> &[T] { + self + } + + /// Extracts a mutable slice of the entire vector. + /// + /// Equivalent to `&mut s[..]`. + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self + } + + /// Returns an unsafe mutable pointer to the vector's buffer, or a dan= gling + /// raw pointer valid for zero sized reads if the vector didn't alloca= te. + #[inline] + pub fn as_mut_ptr(&self) -> *mut T { + self.ptr.as_ptr() + } + + /// Returns a raw pointer to the slice's buffer. + #[inline] + pub fn as_ptr(&self) -> *const T { + self.as_mut_ptr() + } + + /// Returns `true` if the vector contains no elements. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{flags::*, KVec}; + /// + /// let mut v =3D KVec::new(); + /// assert!(v.is_empty()); + /// + /// v.push(1, GFP_KERNEL); + /// assert!(!v.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.len() =3D=3D 0 + } + + /// Like `new`, but parameterized over the choice of allocator for the= returned `KVec`. + #[inline] + pub const fn new_alloc(alloc: A) -> Self { + Self { + ptr: Unique::dangling(), + cap: 0, + len: 0, + alloc, + } + } + + fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { + // Note: + // This method is not implemented in terms of `split_at_spare_mut`, + // to prevent invalidation of pointers to the buffer. + unsafe { + slice::from_raw_parts_mut( + self.as_mut_ptr().add(self.len) as *mut MaybeUninit, + self.capacity() - self.len, + ) + } + } + + /// Appends an element to the back of the [`KVec`] instance. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{flags::*, KVec}; + /// + /// let mut v =3D KVec::new(); + /// v.push(1, GFP_KERNEL)?; + /// assert_eq!(&v, &[1]); + /// + /// v.push(2, GFP_KERNEL)?; + /// assert_eq!(&v, &[1, 2]); + /// # Ok::<(), Error>(()) + /// ``` + pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { + KVec::reserve(self, 1, flags)?; + let s =3D self.spare_capacity_mut(); + s[0].write(v); + + // SAFETY: We just initialised the first spare entry, so it is saf= e to increase the length + // by 1. We also know that the new length is <=3D capacity because= of the previous call to + // `reserve` above. + unsafe { self.set_len(self.len() + 1) }; + Ok(()) + } + + /// Creates a new [`KVec`] instance with at least the given capacity. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{allocator::Kmalloc, flags::*, KVec}; + /// + /// let v =3D KVec::::with_capacity_alloc(20, Kmalloc, GFP_KER= NEL)?; + /// + /// assert!(v.capacity() >=3D 20); + /// # Ok::<(), Error>(()) + /// ``` + pub fn with_capacity_alloc( + capacity: usize, + alloc: A, + flags: Flags, + ) -> Result { + let mut v =3D KVec::new_alloc(alloc); + + Self::reserve(&mut v, capacity, flags)?; + + Ok(v) + } + + /// Pushes clones of the elements of slice into the [`KVec`] instance. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{allocator::Kmalloc, flags::*, KVec}; + /// + /// let mut v =3D KVec::new_alloc(Kmalloc); + /// v.push(1, GFP_KERNEL)?; + /// + /// v.extend_from_slice(&[20, 30, 40], GFP_KERNEL)?; + /// assert_eq!(&v, &[1, 20, 30, 40]); + /// + /// v.extend_from_slice(&[50, 60], GFP_KERNEL)?; + /// assert_eq!(&v, &[1, 20, 30, 40, 50, 60]); + /// # Ok::<(), Error>(()) + /// ``` + pub fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Resu= lt<(), AllocError> + where + T: Clone, + { + self.reserve(other.len(), flags)?; + for (slot, item) in core::iter::zip(self.spare_capacity_mut(), oth= er) { + slot.write(item.clone()); + } + + // SAFETY: We just initialised the `other.len()` spare entries, so= it is safe to increase + // the length by the same amount. We also know that the new length= is <=3D capacity because + // of the previous call to `reserve` above. + unsafe { self.set_len(self.len() + other.len()) }; + Ok(()) + } + + /// Creates a KVec directly from a pointer, a length, a capacity= , and an allocator. + /// + /// # Safety + /// + /// This is highly unsafe, due to the number of invariants that aren= =E2=80=99t checked: + /// + /// - `ptr` must be currently allocated via the given allocator `alloc= `. + /// - `T` needs to have the same alignment as what `ptr` was allocated= with. (`T` having a less + /// strict alignment is not sufficient, the alignment really needs t= o be equal to satisfy the + /// `dealloc` requirement that memory must be allocated and dealloca= ted with the same layout.) + /// - The size of `T` times the `capacity` (i.e. the allocated size in= bytes) needs to be + /// smaller or equal the size the pointer was allocated with. + /// - `length` needs to be less than or equal to `capacity`. + /// - The first `length` values must be properly initialized values of= type `T`. + /// - The allocated size in bytes must be no larger than `isize::MAX`.= See the safety + /// documentation of `pointer::offset`. + /// + /// # Examples + /// + /// ``` + /// let mut v =3D kernel::kvec![1, 2, 3]?; + /// v.reserve(1, GFP_KERNEL)?; + /// + /// let (mut ptr, mut len, cap, alloc) =3D v.into_raw_parts_alloc(); + /// + /// unsafe { ptr.add(len).write(4) }; + /// len +=3D 1; + /// + /// let v =3D unsafe { KVec::from_raw_parts_alloc(ptr, len, cap, alloc= ) }; + /// + /// assert_eq!(v, [1, 2, 3, 4]); + /// + /// # Ok::<(), Error>(()) + /// ``` + pub unsafe fn from_raw_parts_alloc( + ptr: *mut T, + length: usize, + capacity: usize, + alloc: A, + ) -> Self { + let cap =3D if Self::is_zst() { 0 } else { capacity }; + + Self { + ptr: unsafe { Unique::new_unchecked(ptr) }, + cap, + len: length, + alloc, + } + } + + /// Decomposes a `KVec` into its raw components: (`pointer`, `le= ngth`, `capacity`, + /// `allocator`). + pub fn into_raw_parts_alloc(self) -> (*mut T, usize, usize, A) { + let me =3D ManuallyDrop::new(self); + let len =3D me.len(); + let capacity =3D me.capacity(); + let ptr =3D me.as_mut_ptr(); + let alloc =3D unsafe { ptr::read(me.allocator()) }; + (ptr, len, capacity, alloc) + } + + /// Ensures that the capacity exceeds the length by at least `addition= al` elements. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::{allocator::Kmalloc, flags::*, KVec}; + /// + /// let mut v =3D KVec::new_alloc(Kmalloc); + /// v.push(1, GFP_KERNEL)?; + /// + /// v.reserve(10, GFP_KERNEL)?; + /// let cap =3D v.capacity(); + /// assert!(cap >=3D 10); + /// + /// v.reserve(10, GFP_KERNEL)?; + /// let new_cap =3D v.capacity(); + /// assert_eq!(new_cap, cap); + /// + /// # Ok::<(), Error>(()) + /// ``` + pub fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(= ), AllocError> { + let len =3D self.len(); + let cap =3D self.capacity(); + + if cap - len >=3D additional { + return Ok(()); + } + + if Self::is_zst() { + // The capacity is already `usize::MAX` for SZTs, we can't go = higher. + return Err(AllocError); + } + + // We know cap is <=3D `isize::MAX` because `Layout::array` fails = if the resulting byte size + // is greater than `isize::MAX`. So the multiplication by two won'= t overflow. + let new_cap =3D core::cmp::max(cap * 2, len.checked_add(additional= ).ok_or(AllocError)?); + let layout =3D core::alloc::Layout::array::(new_cap).map_err(|_= | AllocError)?; + + // We need to make sure that `ptr` is either NULL or comes from a = previous call to + // `realloc_flags`. A `KVec`'s `ptr` value is not guaranteed= to be NULL and might be + // dangling after being created with `KVec::new`. Instead, we can = rely on `KVec`'s + // capacity to be zero if no memory has been allocated yet. + let ptr =3D if cap =3D=3D 0 { + ptr::null_mut() + } else { + self.as_mut_ptr() + }; + + // SAFETY: `ptr` is valid because it's either NULL or comes from a= previous call to + // `krealloc_aligned`. We also verified that the type is not a ZST. + let ptr =3D unsafe { + self.alloc + .realloc(ptr.cast(), Self::buffer_size(cap)?, layout, flag= s) + }?; + + self.ptr =3D ptr.cast().into(); + self.cap =3D new_cap; + + Ok(()) + } +} + +impl KVec { + /// Extend the vector by `n` clones of value. + pub fn extend_with(&mut self, n: usize, value: T, flags: Flags) -> Res= ult<(), AllocError> { + self.reserve(n, flags)?; + + unsafe { + let mut ptr =3D self.as_mut_ptr().add(self.len()); + + // Write all elements except the last one + for _ in 1..n { + ptr::write(ptr, value.clone()); + ptr =3D ptr.add(1); + } + + if n > 0 { + // We can write the last element directly without cloning = needlessly + ptr::write(ptr, value); + } + } + + // SAFETY: `self.reserve` not bailing out with an error guarantees= that we're not + // exceeding the capacity of this `KVec`. + unsafe { self.set_len(self.len() + n) }; + + Ok(()) + } + + /// Create a new `KVec and extend it by `n` clones of value. + pub fn from_elem(value: T, n: usize, alloc: A, flags: Flags) -> Result= { + let mut v =3D Self::with_capacity_alloc(n, alloc, flags)?; + + v.extend_with(n, value, flags)?; + + Ok(v) + } +} + +impl Drop for KVec +where + A: Allocator, +{ + fn drop(&mut self) { + // SAFETY: We need to drop the vector's elements in place, before = we free the backing + // memory. + unsafe { + core::ptr::drop_in_place(core::ptr::slice_from_raw_parts_mut( + self.as_mut_ptr(), + self.len, + )) + }; + + // If `cap =3D=3D 0` we never allocated any memory in the first pl= ace. + if self.cap !=3D 0 { + // SAFETY: `self.ptr` was previously allocated with `self.allo= c`. + unsafe { self.alloc.free(self.as_mut_ptr().cast()) }; + } + } +} + +impl Default for KVec { + #[inline] + fn default() -> Self { + Self::new() + } +} + +impl fmt::Debug for KVec { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl Deref for KVec +where + A: Allocator, +{ + type Target =3D [T]; + + #[inline] + fn deref(&self) -> &[T] { + unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } + } +} + +impl DerefMut for KVec +where + A: Allocator, +{ + #[inline] + fn deref_mut(&mut self) -> &mut [T] { + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } + } +} + +impl Eq for KVec where A: Allocator {} + +impl, A> Index for KVec +where + A: Allocator, +{ + type Output =3D I::Output; + + #[inline] + fn index(&self, index: I) -> &Self::Output { + Index::index(&**self, index) + } +} + +impl, A> IndexMut for KVec +where + A: Allocator, +{ + #[inline] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + IndexMut::index_mut(&mut **self, index) + } +} + +macro_rules! __impl_slice_eq { + ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) =3D> { + impl PartialEq<$rhs> for $lhs + where + T: PartialEq, + $($ty: $bound)? + { + #[inline] + fn eq(&self, other: &$rhs) -> bool { self[..] =3D=3D other[..]= } + } + } +} + +__impl_slice_eq! { [A1: Allocator, A2: Allocator] KVec, KVec= } +__impl_slice_eq! { [A: Allocator] KVec, &[U] } +__impl_slice_eq! { [A: Allocator] KVec, &mut [U] } +__impl_slice_eq! { [A: Allocator] &[T], KVec } +__impl_slice_eq! { [A: Allocator] &mut [T], KVec } +__impl_slice_eq! { [A: Allocator] KVec, [U] } +__impl_slice_eq! { [A: Allocator] [T], KVec } +__impl_slice_eq! { [A: Allocator, const N: usize] KVec, [U; N] } +__impl_slice_eq! { [A: Allocator, const N: usize] KVec, &[U; N] } diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index 20112233d750..0ee3f0d203e2 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -14,7 +14,7 @@ #[doc(no_inline)] pub use core::pin::Pin; =20 -pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox}; +pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox, KVec}; =20 #[doc(no_inline)] pub use alloc::vec::Vec; --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 270C01B47DE for ; Thu, 4 Jul 2024 17:09:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112957; cv=none; b=Y+dBjqIlVN1bEY5/sSDSJG3iBHKCn9mu8ktktA5HQ5nTxL2hzGvhhrouaGggbB8QezSeYsIszJ3t5krQQRnKXdsDjvAOoHO14pa4QXSHK7o2TcbXrVlKAEmqEDcmcRMYVHvNQ7QzGV+O9eRjn3/gQUUjR/kT+jl/DPjmTQviYC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112957; c=relaxed/simple; bh=CPyHMERj1twQjcjGyBr1Olj39ha/kHj+F1ifWXerf6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mbgxAu+l1nsdC7hX51AtwQ+i8RjcGgJko/3PlM3822YN2rSqYYM49wKgYMXcm53ZLlmojlvlGujgMrEjgZ77yGkvstjLcja1Y7WwdenUwZiQE5Yvh2xoU5faBRUl93aHQnpwirNAdhWm6JToOM4ahKEfn9m4vImp59NWbq44nO0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=YsTd4oqT; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="YsTd4oqT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112955; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fpg1faBr5ekWLp/A+ticofxlpAUVrowaMF9N+c1VH5Y=; b=YsTd4oqTOnYC9SqdO7d7/E75/fRsIAcA2CLlUl204rEki/9syQdRMjtru6+YSCf7sS1Txg v+Su+VwZtgIE0V+s+mT0pKSi5Fk9qDPcxp2jftcFvJ0OeVFCx1yWBUtgTTVTZYQnGcvvaA 3vempKubMlCLI/d+A1FkuEUATxRqv58= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-534-QlrzO6nRMFegnWNM5i7t6Q-1; Thu, 04 Jul 2024 13:09:11 -0400 X-MC-Unique: QlrzO6nRMFegnWNM5i7t6Q-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4256569a4faso10627395e9.1 for ; Thu, 04 Jul 2024 10:09:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112951; x=1720717751; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fpg1faBr5ekWLp/A+ticofxlpAUVrowaMF9N+c1VH5Y=; b=ohDu6aXLQVFQzsBQT/6oobyjw011rSFb/nKq4WSjwJtExEsZLPCsVUjuHpaT9behez DGnZz7a+xZ2yDyeCjHC5qlkOXNBNnkJ91Eekj6/kBGjorb171LgOvPAz15Ub40G/2jcP ax/0diegvJIAyQzbh7jVAcJ4gO15F2186GR+yEEEHAmEVwM0x4mdpMThpCDxvdQKk+xx ol45h8CpeAiPpvsafdoWb6j2AJbAaIeO2coy/E9z5MCBVB6Ls7dGsAEw4Gxx/Ex64tU0 nwHTGmKfizToXhvS1JBmUCtSuzam6ixhg/wferJ8u7CfeKAoKjeisVhr2BLV15dM3yxV c5FQ== X-Forwarded-Encrypted: i=1; AJvYcCUZgVvR0mugixT42+KkcRJAPyRcibRy1O2sqwxGcnqErwSy3RpUgrhvrZwiWpt4m/EpAFK+O6DlbVxjfP76icrSVDmQZd+yaUaMN1xJ X-Gm-Message-State: AOJu0YwgOZLTlkz/vwtvK+oi3JYxYyFtiNqETOxxh+k3YKWFhQ/1vQ9z ojVGCIhMuR399ArS/tmjOiI4C0POBWtvQgo+Nuc/BC5MNBOrQnrltiGyceeX27vFbSMZgKx0ZJD m4DZd0Q8vynw6RagouPRS0ZgOG+1RpNC5TdUBskeN9dRD6D+qNECukrd5DnEyew== X-Received: by 2002:a05:600c:3547:b0:425:7aa7:e490 with SMTP id 5b1f17b1804b1-4264b0c50ecmr19778775e9.3.1720112950780; Thu, 04 Jul 2024 10:09:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFKM4G6SCFeJEZtSOhy82Z2Ed8yGmNU3aqSb//nIUjwTmhfzTkmvAH30VJp4ZwrSb2S0rxzfA== X-Received: by 2002:a05:600c:3547:b0:425:7aa7:e490 with SMTP id 5b1f17b1804b1-4264b0c50ecmr19778665e9.3.1720112950454; Thu, 04 Jul 2024 10:09:10 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a1d165bsm31228875e9.4.2024.07.04.10.09.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:09 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 14/20] rust: alloc: implement `IntoIterator` for `KVec` Date: Thu, 4 Jul 2024 19:06:42 +0200 Message-ID: <20240704170738.3621-15-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement `IntoIterator` for `KVec`, `KVec`'s `IntoIter` type, as well as `Iterator` for `IntoIter`. `KVec::into_iter` disassembles the `KVec` into its raw parts; additionally, `IntoIter` keeps track of a separate pointer, which is incremented correspondingsly as the iterator advances, while the length, or the count of elements, is decremented. This also means that `IntoIter` takes the ownership of the backing buffer and is responsible to drop the remaining elements and free the backing buffer, if it's dropped. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 1 + rust/kernel/alloc/kvec.rs | 177 +++++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index 3a0195d23bb4..e6a5d65e0c48 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -15,6 +15,7 @@ pub use self::allocator_test as allocator; =20 pub use self::kbox::KBox; +pub use self::kvec::IntoIter; pub use self::kvec::KVec; =20 /// Indicates an allocation error. diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index 7ec898657832..ece48930966e 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -11,7 +11,9 @@ ops::DerefMut, ops::Index, ops::IndexMut, - ptr, slice, + ptr, + ptr::NonNull, + slice, slice::SliceIndex, }; =20 @@ -603,3 +605,176 @@ fn eq(&self, other: &$rhs) -> bool { self[..] =3D=3D = other[..] } __impl_slice_eq! { [A: Allocator] [T], KVec } __impl_slice_eq! { [A: Allocator, const N: usize] KVec, [U; N] } __impl_slice_eq! { [A: Allocator, const N: usize] KVec, &[U; N] } + +impl<'a, T, A> IntoIterator for &'a KVec +where + A: Allocator, +{ + type Item =3D &'a T; + type IntoIter =3D slice::Iter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, T, A: Allocator> IntoIterator for &'a mut KVec +where + A: Allocator, +{ + type Item =3D &'a mut T; + type IntoIter =3D slice::IterMut<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +/// An iterator that moves out of a vector. +/// +/// This `struct` is created by the `into_iter` method on [`KVec`] (provid= ed by the [`IntoIterator`] +/// trait). +/// +/// # Examples +/// +/// ``` +/// let v =3D kernel::kvec![0, 1, 2]?; +/// let iter: kernel::alloc::IntoIter<_> =3D v.into_iter(); +/// +/// # Ok::<(), Error>(()) +/// ``` +pub struct IntoIter { + ptr: *mut T, + buf: NonNull, + len: usize, + cap: usize, + alloc: A, +} + +impl IntoIter +where + A: Allocator, +{ + fn as_raw_mut_slice(&mut self) -> *mut [T] { + ptr::slice_from_raw_parts_mut(self.ptr, self.len) + } +} + +impl Iterator for IntoIter +where + A: Allocator, +{ + type Item =3D T; + + /// # Examples + /// + /// ``` + /// let v =3D kernel::kvec![1, 2, 3]?; + /// let mut it =3D v.into_iter(); + /// + /// assert_eq!(it.next(), Some(1)); + /// assert_eq!(it.next(), Some(2)); + /// assert_eq!(it.next(), Some(3)); + /// assert_eq!(it.next(), None); + /// + /// # Ok::<(), Error>(()) + /// ``` + fn next(&mut self) -> Option { + if self.len =3D=3D 0 { + return None; + } + + let ptr =3D self.ptr; + if !KVec::::is_zst() { + // SAFETY: We can't overflow; `end` is guaranteed to mark the = end of the buffer. + unsafe { self.ptr =3D self.ptr.add(1) }; + } else { + // For ZST `ptr` has to stay where it is to remain aligned, so= we just reduce `self.len` + // by 1. + } + self.len -=3D 1; + + // SAFETY: `ptr` is guaranteed to point at a valid element within = the buffer. + Some(unsafe { ptr.read() }) + } + + /// # Examples + /// + /// ``` + /// use kernel::alloc::KVec; + /// + /// let v: KVec =3D kernel::kvec![1, 2, 3]?; + /// let mut iter =3D v.into_iter(); + /// let size =3D iter.size_hint().0; + /// + /// iter.next(); + /// assert_eq!(iter.size_hint().0, size - 1); + /// + /// iter.next(); + /// assert_eq!(iter.size_hint().0, size - 2); + /// + /// iter.next(); + /// assert_eq!(iter.size_hint().0, size - 3); + /// + /// # Ok::<(), Error>(()) + /// ``` + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl Drop for IntoIter +where + A: Allocator, +{ + fn drop(&mut self) { + // SAFETY: Drop the remaining vector's elements in place, before w= e free the backing + // memory. + unsafe { ptr::drop_in_place(self.as_raw_mut_slice()) }; + + // If `cap =3D=3D 0` we never allocated any memory in the first pl= ace. + if self.cap !=3D 0 { + // SAFETY: `self.buf` was previously allocated with `self.allo= c`. + unsafe { self.alloc.free(self.buf.as_ptr().cast()) }; + } + } +} + +impl IntoIterator for KVec +where + A: Allocator, +{ + type Item =3D T; + type IntoIter =3D IntoIter; + + /// Creates a consuming iterator, that is, one that moves each value o= ut of + /// the vector (from start to end). The vector cannot be used after ca= lling + /// this. + /// + /// # Examples + /// + /// ``` + /// let v =3D kernel::kvec![1, 2]?; + /// let mut v_iter =3D v.into_iter(); + /// + /// let first_element: Option =3D v_iter.next(); + /// + /// assert_eq!(first_element, Some(1)); + /// assert_eq!(v_iter.next(), Some(2)); + /// assert_eq!(v_iter.next(), None); + /// + /// # Ok::<(), Error>(()) + /// ``` + #[inline] + fn into_iter(self) -> Self::IntoIter { + let (ptr, len, cap, alloc) =3D self.into_raw_parts_alloc(); + + IntoIter { + ptr, + buf: unsafe { NonNull::new_unchecked(ptr) }, + len, + cap, + alloc, + } + } +} --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A2191C8FA3 for ; Thu, 4 Jul 2024 17:09:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112960; cv=none; b=Ad2Nl+7rCMRALPJl1OLiHWPf4jpE0kXkxygx2ZYVxBgrFm8csxT/AfYvvDG1Ke+hlt1TcNtoBCSUepKlbYYcsJUpYPfSNZMSo02G7ynS/68t//YP/+7SGPtlIckTV8CJiBWwYimMZEelFOT+hmPnW7ZvPzQ2rNGQXRgPxK1QTEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112960; c=relaxed/simple; bh=XUc7v1nO5kUdQAl7vZK4cJjjtrbiSJ6BexnC7Evs9nk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C5QWG70NugSwmXewmZrl7gcbO9nnva8U+OjV+zs23jN4i4of1E2V5GvhD35VCxwXbnTMKByZVym+vxAFgvjWwxWD22ayM6jX6r5lQbkDB8zp1TpLRpXMIwf+ND8ntcehsVP0ViZ88ReseM9Nt2knzcYPaYoUCocZXr0rv8hwaRs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=DnIq5kX6; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="DnIq5kX6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112957; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JZPhE3XC9UV6OvChFdMEzQxeZVNAagRt/GzQJe2dQ8k=; b=DnIq5kX63T3JiwmnPN6FRw02Jk3B4JI5Sj9h2qDMcjjcz3NLBVBD6g4V8kabljRR4N+OVm o8AxumMl69aPMHxRi70aQVyWuWTS9MtYN1W+7fqodBsl98Hrigaadrr81z6C4bO7uRaJiy v6WeRb0X7FMGgVDHWRn9L9C2V+1jMYk= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-346-kFlJSzhePBWapK3svjrUlw-1; Thu, 04 Jul 2024 13:09:16 -0400 X-MC-Unique: kFlJSzhePBWapK3svjrUlw-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4246cf4c87dso5503785e9.2 for ; Thu, 04 Jul 2024 10:09:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112955; x=1720717755; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JZPhE3XC9UV6OvChFdMEzQxeZVNAagRt/GzQJe2dQ8k=; b=AWzE3mnUDLZgAAu0itKCYUk00PI/7oreSmWCtUaZHOQKs/F0jaABLMS+NooB9ThncZ AAYtRlJE6MssmHPVs260/W/7WCn5j9l0nndSHZde7x6WcB87//yea5+DrasJ4UL3JHJf PfZXsTxbhyoohXb53HpqpP5f0gqjrWprzQrjYeF6dfDMhbNPlYAF209e4Op+0tzZG1MC sPUnAmowwFd3QmvOsYENwRi+sJUXpIsBGLbAKybX7PUhmGaALGf4rXpw2qqNIJHYWAQZ skKxzQEELHvE1r6/QZxhHCsNVFdntUYz4TK3U2Y/LJB2XX4thBlc2FOUzSXvnSB9ukIC jaTQ== X-Forwarded-Encrypted: i=1; AJvYcCVUnmIyY4NdQFQPFuaI259QDmg3ESm7JX4WCXjfrBGcr4ylWgR9D1DEaWDkDLikHPclva4PDLiBFmJVHCAZ6ZZ/ptG3jGAoLGWTWRjX X-Gm-Message-State: AOJu0YxkwjlpIQl9R2JKn2rGkfmPjSFv14LhtaVbzAgJk19t3dTq1vVQ x6WjBOUUhpf3ydvz49+QCbhDgOTrPmgJNFRDz1s4uluJJZPEDR4dlfh9gcf+hZNUNtiXr8wjVDU C5nOE1Uenme5eGue/VkHSC4CX6OM1CU8UhNXGNUwd9xqhgTu7TDWpYYx0S2nitw== X-Received: by 2002:a7b:c8d4:0:b0:423:6b7:55eb with SMTP id 5b1f17b1804b1-4264a3e1d00mr19233055e9.14.1720112954932; Thu, 04 Jul 2024 10:09:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFm7N1rZxpiePn941cG0nEN6av+LSSyouCyLUvG8v66AJo5NSOJhREMWyUxMtjj/QKi8dkOYQ== X-Received: by 2002:a7b:c8d4:0:b0:423:6b7:55eb with SMTP id 5b1f17b1804b1-4264a3e1d00mr19232875e9.14.1720112954604; Thu, 04 Jul 2024 10:09:14 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a1d510bsm31761725e9.3.2024.07.04.10.09.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:14 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 15/20] rust: alloc: implement `collect` for `IntoIter` Date: Thu, 4 Jul 2024 19:06:43 +0200 Message-ID: <20240704170738.3621-16-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, we can't implement `FromIterator`. There are a couple of issues with this trait in the kernel, namely: - Rust's specialization feature is unstable. This prevents us to optimze for the special case where `I::IntoIter` equals `KVec`'s `IntoIter` type. - We also can't use `I::IntoIter`'s type ID either to work around this, since `FromIterator` doesn't require this type to be `'static`. - `FromIterator::from_iter` does return `Self` instead of `Result`, hence we can't properly handle allocation failures. - Neither `Iterator::collect` nor `FromIterator::from_iter` can handle additional allocation flags. Instead, provide `IntoIter::collect`, such that we can at least convert `IntoIter` into a `KVec` again. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc/kvec.rs | 83 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index ece48930966e..463c8910c23c 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -2,7 +2,7 @@ =20 //! Implementation of [`KVec`]. =20 -use super::{allocator::Kmalloc, AllocError, Allocator, Flags}; +use super::{allocator::Kmalloc, flags::*, AllocError, Allocator, Flags}; use crate::types::Unique; use core::{ fmt, @@ -658,6 +658,87 @@ impl IntoIter fn as_raw_mut_slice(&mut self) -> *mut [T] { ptr::slice_from_raw_parts_mut(self.ptr, self.len) } + + fn allocator(&self) -> &A { + &self.alloc + } + + fn into_raw_parts(self) -> (*mut T, NonNull, usize, usize, A) { + let me =3D ManuallyDrop::new(self); + let ptr =3D me.ptr; + let buf =3D me.buf; + let len =3D me.len; + let cap =3D me.cap; + let alloc =3D unsafe { ptr::read(me.allocator()) }; + (ptr, buf, len, cap, alloc) + } + + /// Same as `Iterator::collect` but specialized for `KVec`'s `IntoIter= `. + /// + /// Currently, we can't implement `FromIterator`. There are a couple o= f issues with this trait + /// in the kernel, namely: + /// + /// - Rust's specialization feature is unstable. This prevents us to o= ptimze for the special + /// case where `I::IntoIter` equals `KVec`'s `IntoIter` type. + /// - We also can't use `I::IntoIter`'s type ID either to work around = this, since `FromIterator` + /// doesn't require this type to be `'static`. + /// - `FromIterator::from_iter` does return `Self` instead of `Result<= Self, AllocError>`, hence + /// we can't properly handle allocation failures. + /// - Neither `Iterator::collect` nor `FromIterator::from_iter` can ha= ndle additional allocation + /// flags. + /// + /// Instead, provide `IntoIter::collect`, such that we can at least co= nvert a `IntoIter` into a + /// `KVec` again. + /// + /// Note that `IntoIter::collect` doesn't require `Flags`, since it re= -uses the existing backing + /// buffer. However, this backing buffer may be shrunk to the actual c= ount of elements. + /// + /// # Examples + /// + /// ``` + /// let v =3D kernel::kvec![1, 2, 3]?; + /// let mut it =3D v.into_iter(); + /// + /// assert_eq!(it.next(), Some(1)); + /// + /// let v =3D it.collect()?; + /// assert_eq!(v, [2, 3]); + /// + /// # Ok::<(), Error>(()) + /// ``` + pub fn collect(self) -> Result, AllocError> { + let (mut ptr, buf, len, mut cap, alloc) =3D self.into_raw_parts(); + let has_advanced =3D ptr !=3D buf.as_ptr(); + + if has_advanced { + // SAFETY: Copy the contents we have advanced to at the beginn= ing of the buffer. + // `ptr` is guaranteed to be between `buf` and `buf.add(cap)` = and `ptr.add(len)` is + // guaranteed to be smaller than `buf.add(cap)`. + unsafe { ptr::copy(ptr, buf.as_ptr(), len) }; + ptr =3D buf.as_ptr(); + } + + // Do not allow for too much spare capacity. + if len < cap / 2 { + let layout =3D core::alloc::Layout::array::(len).map_err(|_= | AllocError)?; + // SAFETY: `ptr` points to the start of the backing buffer, `c= ap` is the capacity of + // the original `KVec` and `len` is guaranteed to be smaller t= han `cap`. Depending on + // `alloc` this operation may shrink the buffer or leaves it a= s it is. + ptr =3D unsafe { + alloc.realloc(ptr.cast(), KVec::::buffer_size(cap)?, la= yout, GFP_KERNEL) + }? + .as_ptr() + .cast(); + cap =3D len; + } + + // SAFETY: If the iterator has been advanced, the advanced element= s have been copied to + // the beginning of the buffer and `len` has been adjusted accordi= ngly. `ptr` is guaranteed + // to point to the start of the backing buffer. `cap` is either th= e original capacity or, + // after shrinking the buffer, equal to `len`. `alloc` is guarante= ed to be unchanged since + // `into_iter` has been called on the original `KVec`. + Ok(unsafe { KVec::from_raw_parts_alloc(ptr, len, cap, alloc) }) + } } =20 impl Iterator for IntoIter --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1BFA1CF3DA for ; Thu, 4 Jul 2024 17:09:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112964; cv=none; b=HUaDQ9UibduVSErIxsVlAmWPMa5lKF4ppKmWLeTcqaxv/+altvH+JLkaiCapZRMxHoyDF91fMyVQPlvoSz7xegw5tY20IuPKYj2gkUttuunb0OG3XODD+4aHYyYrXTANBGvVsRl3FKgO8cLHfWAail+oV7c7/jSy5L9lyx2PG7Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112964; c=relaxed/simple; bh=XaoL+c3CKcLGkGaS6dN6gGgH1UcvqowfyMOc7PMR0Mw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sL3ujwvj5IbtTHofydXTEBJjjGtigR0csOrjY5KY92RnConKEb1Bb3r+LhTFPoXv9Y5w4wqQGwVKXrj0pD3Dt29tyVCpwtZKerJg6bmv1YJSdGACbimZ9uyf6ESPjjzOyySwGeaO3fQ8vBJlYLKVt9uQemRkXDu3zscTVyMEOk0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=B1no5Vrb; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="B1no5Vrb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112962; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0zplR95ywjysz6XCCMayD+WP0RtbZS0dmGGMbrdUaAU=; b=B1no5VrbLFwm03OavJmIEtIrlou5bN6/P0gd5lAGcDeVXFsmZ68pnByt/BhdmKRGea9+6j IT73bhEbfJK6s/JFEvPDCHnZoyZbtGeotu/2QCw7+jY7hYUEjoZ28CACCqz3LJkOQQ6kdV rz0+MUGft+RDGDTkBn/qCSxAyV4Rtyg= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-397-vep26zuAO3CRirSvkoidmw-1; Thu, 04 Jul 2024 13:09:21 -0400 X-MC-Unique: vep26zuAO3CRirSvkoidmw-1 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-52e969d0198so921166e87.2 for ; Thu, 04 Jul 2024 10:09:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112959; x=1720717759; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0zplR95ywjysz6XCCMayD+WP0RtbZS0dmGGMbrdUaAU=; b=XqJbAU3zs/alIFRtxelZpOstXJ6nlYBLjdsA0QUFVRQrBdfH65aHW+Q7shcw49BG7Q nP78bUadZ6ztOXVgsOZubcnxTRLoxdA2wY/K0z7WLfvzCLcqXc20thsLNyiAGvrxxmZO JRU3JYdGvOphg/TIxtAVLEXrMkFHnDgyL4zHE7KmG8LtjTz0QoOBLK4MFbNkndU/0lmG 6JC6FVjmvJ1DsS8nKGLPH7aep1Y3/S+1v6lp1K+Yc+mhWvVBEprUEdZe6nxwo0hphb79 T+FUOcFAsbFPKY4tlZ+Wb851txoVeXE/F02uZFOXz6nLHWSVYMXPeyHbSSO1x3raMBPU hQfw== X-Forwarded-Encrypted: i=1; AJvYcCUGslvbUW9zpUyJZuICBnFF0HdUtJBiYTZ1WRz6dUIB+DFVcjJJPPLOK27K0HMh6uk812eMxdtLh3dlU4Z3n7KaC6u8FSKdY/CpQag7 X-Gm-Message-State: AOJu0Yxt2F1YA8QOKuyIqRoFb7yV8frVlgotVsrdyiruALmMLYVC1I/P JlZIfYijEdfW1B0PlTtl39LIMLiD1kYIpvBMpnmJBG2rroRq2Uzegrzn/CZCAMgO+mE8tXRQ22h 2RHGRETHYpiGTCUrtIyB4IVoSs1otX0HjlE5MqhcUU19Pj7pTmvop2VHqzFDuMisQu8yWEA== X-Received: by 2002:ac2:4436:0:b0:52c:df77:6507 with SMTP id 2adb3069b0e04-52ea0641231mr1734208e87.37.1720112959049; Thu, 04 Jul 2024 10:09:19 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFn5MmEc0L9zeEIwNR+k6aoMoK9A1IqV3mcSkP+FvZJEBEpoHcx3+B4DzC1hITE2cXFqTfSvQ== X-Received: by 2002:ac2:4436:0:b0:52c:df77:6507 with SMTP id 2adb3069b0e04-52ea0641231mr1734171e87.37.1720112958598; Thu, 04 Jul 2024 10:09:18 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a2fc8bcsm30972425e9.44.2024.07.04.10.09.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:18 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 16/20] rust: treewide: switch to `KVec` Date: Thu, 4 Jul 2024 19:06:44 +0200 Message-ID: <20240704170738.3621-17-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that we got `KVec` in place, convert all existing `Vec` users to `KVec`. Signed-off-by: Danilo Krummrich --- rust/kernel/str.rs | 12 +++++------- rust/kernel/sync/locked_by.rs | 2 +- rust/kernel/types.rs | 2 +- samples/rust/rust_minimal.rs | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index bb8d4f41475b..0b6ffbade521 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -2,8 +2,7 @@ =20 //! String representations. =20 -use crate::alloc::{flags::*, vec_ext::VecExt, AllocError}; -use alloc::vec::Vec; +use crate::alloc::{flags::*, AllocError, KVec}; use core::fmt::{self, Write}; use core::ops::{self, Deref, DerefMut, Index}; =20 @@ -790,7 +789,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result { /// assert_eq!(s.is_ok(), false); /// ``` pub struct CString { - buf: Vec, + buf: KVec, } =20 impl CString { @@ -803,7 +802,7 @@ pub fn try_from_fmt(args: fmt::Arguments<'_>) -> Result= { let size =3D f.bytes_written(); =20 // Allocate a vector with the required number of bytes, and write = to it. - let mut buf =3D as VecExt<_>>::with_capacity(size, GFP_KER= NEL)?; + let mut buf =3D KVec::with_capacity(size, GFP_KERNEL)?; // SAFETY: The buffer stored in `buf` is at least of size `size` a= nd is valid for writes. let mut f =3D unsafe { Formatter::from_buffer(buf.as_mut_ptr(), si= ze) }; f.write_fmt(args)?; @@ -850,10 +849,9 @@ impl<'a> TryFrom<&'a CStr> for CString { type Error =3D AllocError; =20 fn try_from(cstr: &'a CStr) -> Result { - let mut buf =3D Vec::new(); + let mut buf =3D KVec::new(); =20 - as VecExt<_>>::extend_from_slice(&mut buf, cstr.as_bytes_w= ith_nul(), GFP_KERNEL) - .map_err(|_| AllocError)?; + KVec::extend_from_slice(&mut buf, cstr.as_bytes_with_nul(), GFP_KE= RNEL)?; =20 // INVARIANT: The `CStr` and `CString` types have the same invaria= nts for // the string data, and we copied it over without changes. diff --git a/rust/kernel/sync/locked_by.rs b/rust/kernel/sync/locked_by.rs index babc731bd5f6..b94517231fcc 100644 --- a/rust/kernel/sync/locked_by.rs +++ b/rust/kernel/sync/locked_by.rs @@ -43,7 +43,7 @@ /// struct InnerDirectory { /// /// The sum of the bytes used by all files. /// bytes_used: u64, -/// _files: Vec, +/// _files: KVec, /// } /// /// struct Directory { diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 0b2a3ce538a6..5ef52d46a386 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -155,7 +155,7 @@ unsafe fn from_foreign(_: *const core::ffi::c_void) -> = Self {} /// # use kernel::types::ScopeGuard; /// fn example3(arg: bool) -> Result { /// let mut vec =3D -/// ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {}= elements\n", v.len())); +/// ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {= } elements\n", v.len())); /// /// vec.push(10u8, GFP_KERNEL)?; /// if arg { diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs index 2a9eaab62d1c..4aaf117bf8e3 100644 --- a/samples/rust/rust_minimal.rs +++ b/samples/rust/rust_minimal.rs @@ -13,7 +13,7 @@ } =20 struct RustMinimal { - numbers: Vec, + numbers: KVec, } =20 impl kernel::Module for RustMinimal { @@ -21,7 +21,7 @@ fn init(_module: &'static ThisModule) -> Result { pr_info!("Rust minimal sample (init)\n"); pr_info!("Am I built-in? {}\n", !cfg!(MODULE)); =20 - let mut numbers =3D Vec::new(); + let mut numbers =3D KVec::new(); numbers.push(72, GFP_KERNEL)?; numbers.push(108, GFP_KERNEL)?; numbers.push(200, GFP_KERNEL)?; --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C2B31CFD43 for ; Thu, 4 Jul 2024 17:09:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112969; cv=none; b=mmikiisHok9bdJVpBWD54k8gQGsT8ISdhdqG5FUyXIRYoigKB30nY9XCZiexD+xiDAHhZMUvozPkelgRFRR5Un2oNICdc0+kdntb62sabLIjsyxnL6IDwvxlg8vMD8tmshZic/yutvOHtHYfsaJMb+wVlBlTIAsasSwecxkRx6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112969; c=relaxed/simple; bh=unZd8SNo4EyBPZwAOYtJ6SCq7DPMNM2ujfeIqLeIoPs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PqCFr5L2cIKVq3zrn4ZIBUgg/2jlSDkCdCXRiEJnmxX0s52pDMrywByIhWNh8SUVVa2avSqkNnkdFVhHGi1NgaiAxfM8Ig6G0Eb+SFfSf3O0dkrU1ygxizyWt8wA8oDS866vQfiW6nHO2+VLONITIkKSta5R9NLdi+1lwUqk4jE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=evwFRpip; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="evwFRpip" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112966; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D0CT3DkkY+yNqCNHJuyWLBFD/Y9xzpFr8fJwqHRElVo=; b=evwFRpipyuYydY4UXdUQ2Ndyv6zSYPiV51CBHTlxl7eiKS2wO0Xx1hjsBVFbe7yHrpTBZL g/RUxFJ/rzBi5QPJrQCtDZyE4Ld4naIAN1mxzLprhqOV22PkJGY/gk4r6CBrDhbh38HZbY 2/l1I2DCtQCTMagq3BcwGo0b3JOXPcw= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-341-xQe3NCOdNMioEhgKTC0x9A-1; Thu, 04 Jul 2024 13:09:24 -0400 X-MC-Unique: xQe3NCOdNMioEhgKTC0x9A-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4256718144dso8258415e9.1 for ; Thu, 04 Jul 2024 10:09:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112963; x=1720717763; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D0CT3DkkY+yNqCNHJuyWLBFD/Y9xzpFr8fJwqHRElVo=; b=C97SbAwobycSvUN4mxTl4szh5u4yaSMppCzvroU4F4/sBYrnRY/3TddwZbiOQXvDG6 CLT39PJ62acpGdx7UJWSdXRpUkXXmX1pI1E8KvfprWayEpYaPgEs4EFL7CmF2SQ6W1WJ lDc1/uuIhzhP5r53Wuik4FmOwWDuU4g6sSSNR5dtKKDdRsmJ0xxl+SlEYLmF8+g0Y2o6 GMj05SWsvQxVi0ZFP7MnvFePQqMk3BP1cRaLgbdn+eFUNS6pdzszWw4R5QR6kDqGsm4R h7EU+CsoiiR6qwXvnuTZ7PnP8YmIf5EKHQl4rELlIZ176HkTnjM0kSZHh18vIfc4SbfU Mrnw== X-Forwarded-Encrypted: i=1; AJvYcCV/JEa1pVH41sNMykUHZFJKfsNv048Kr/sQnbkQvUvxb75zEGP5VndMPhGQVMzAetlyspyIe4Vqrth26gEpbhZazYYlZO7zZS43zwnA X-Gm-Message-State: AOJu0YwchAdVqeJrqG68WQLoNyJjy4Mya7jN66DX/m7C/S2wOQb244ms Jo3Z7YqrHO90RqA87ZxPyqme6h57ZziQHMA4a+eMubEREl88MOV3e8vBTeOzIZyIeGT+hMECcGB kVgqrzx+Dh3Sj/yrkR7VgBcu5cBKiGBFhETIvKN5lJOkqvKmjTQWOs8w+84bYbg== X-Received: by 2002:a05:600c:12d2:b0:425:73ba:e012 with SMTP id 5b1f17b1804b1-4264a3bc309mr19751585e9.7.1720112962996; Thu, 04 Jul 2024 10:09:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFfh6LXgR2Un18etB/U4D4xFPGKtOmoSHMl3k9SXFcepz5JY5ESDnz4WGx8qOXEK4Bv7oGh0Q== X-Received: by 2002:a05:600c:12d2:b0:425:73ba:e012 with SMTP id 5b1f17b1804b1-4264a3bc309mr19751375e9.7.1720112962569; Thu, 04 Jul 2024 10:09:22 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a2fc8bcsm30974125e9.44.2024.07.04.10.09.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:22 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 17/20] rust: alloc: remove `VecExt` extension Date: Thu, 4 Jul 2024 19:06:45 +0200 Message-ID: <20240704170738.3621-18-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that all existing `Vec` users were moved to `KVec`, remove the `VecExt` extension. Signed-off-by: Danilo Krummrich --- rust/kernel/alloc.rs | 1 - rust/kernel/alloc/vec_ext.rs | 185 ----------------------------------- rust/kernel/prelude.rs | 5 +- 3 files changed, 1 insertion(+), 190 deletions(-) delete mode 100644 rust/kernel/alloc/vec_ext.rs diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs index e6a5d65e0c48..178f556aa7b0 100644 --- a/rust/kernel/alloc.rs +++ b/rust/kernel/alloc.rs @@ -6,7 +6,6 @@ pub mod allocator; pub mod kbox; pub mod kvec; -pub mod vec_ext; =20 #[cfg(any(test, testlib))] pub mod allocator_test; diff --git a/rust/kernel/alloc/vec_ext.rs b/rust/kernel/alloc/vec_ext.rs deleted file mode 100644 index bf277976ed38..000000000000 --- a/rust/kernel/alloc/vec_ext.rs +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -//! Extensions to [`Vec`] for fallible allocations. - -use super::{AllocError, Flags}; -use alloc::vec::Vec; -use core::ptr; - -/// Extensions to [`Vec`]. -pub trait VecExt: Sized { - /// Creates a new [`Vec`] instance with at least the given capacity. - /// - /// # Examples - /// - /// ``` - /// let v =3D Vec::::with_capacity(20, GFP_KERNEL)?; - /// - /// assert!(v.capacity() >=3D 20); - /// # Ok::<(), Error>(()) - /// ``` - fn with_capacity(capacity: usize, flags: Flags) -> Result; - - /// Appends an element to the back of the [`Vec`] instance. - /// - /// # Examples - /// - /// ``` - /// let mut v =3D Vec::new(); - /// v.push(1, GFP_KERNEL)?; - /// assert_eq!(&v, &[1]); - /// - /// v.push(2, GFP_KERNEL)?; - /// assert_eq!(&v, &[1, 2]); - /// # Ok::<(), Error>(()) - /// ``` - fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError>; - - /// Pushes clones of the elements of slice into the [`Vec`] instance. - /// - /// # Examples - /// - /// ``` - /// let mut v =3D Vec::new(); - /// v.push(1, GFP_KERNEL)?; - /// - /// v.extend_from_slice(&[20, 30, 40], GFP_KERNEL)?; - /// assert_eq!(&v, &[1, 20, 30, 40]); - /// - /// v.extend_from_slice(&[50, 60], GFP_KERNEL)?; - /// assert_eq!(&v, &[1, 20, 30, 40, 50, 60]); - /// # Ok::<(), Error>(()) - /// ``` - fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(= ), AllocError> - where - T: Clone; - - /// Ensures that the capacity exceeds the length by at least `addition= al` elements. - /// - /// # Examples - /// - /// ``` - /// let mut v =3D Vec::new(); - /// v.push(1, GFP_KERNEL)?; - /// - /// v.reserve(10, GFP_KERNEL)?; - /// let cap =3D v.capacity(); - /// assert!(cap >=3D 10); - /// - /// v.reserve(10, GFP_KERNEL)?; - /// let new_cap =3D v.capacity(); - /// assert_eq!(new_cap, cap); - /// - /// # Ok::<(), Error>(()) - /// ``` - fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), A= llocError>; -} - -impl VecExt for Vec { - fn with_capacity(capacity: usize, flags: Flags) -> Result { - let mut v =3D Vec::new(); - >::reserve(&mut v, capacity, flags)?; - Ok(v) - } - - fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { - >::reserve(self, 1, flags)?; - let s =3D self.spare_capacity_mut(); - s[0].write(v); - - // SAFETY: We just initialised the first spare entry, so it is saf= e to increase the length - // by 1. We also know that the new length is <=3D capacity because= of the previous call to - // `reserve` above. - unsafe { self.set_len(self.len() + 1) }; - Ok(()) - } - - fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(= ), AllocError> - where - T: Clone, - { - >::reserve(self, other.len(), flags)?; - for (slot, item) in core::iter::zip(self.spare_capacity_mut(), oth= er) { - slot.write(item.clone()); - } - - // SAFETY: We just initialised the `other.len()` spare entries, so= it is safe to increase - // the length by the same amount. We also know that the new length= is <=3D capacity because - // of the previous call to `reserve` above. - unsafe { self.set_len(self.len() + other.len()) }; - Ok(()) - } - - #[cfg(any(test, testlib))] - fn reserve(&mut self, additional: usize, _flags: Flags) -> Result<(), = AllocError> { - Vec::reserve(self, additional); - Ok(()) - } - - #[cfg(not(any(test, testlib)))] - fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), A= llocError> { - let alloc: &dyn super::Allocator =3D &super::allocator::Kmalloc; - let len =3D self.len(); - let cap =3D self.capacity(); - - if cap - len >=3D additional { - return Ok(()); - } - - if core::mem::size_of::() =3D=3D 0 { - // The capacity is already `usize::MAX` for SZTs, we can't go = higher. - return Err(AllocError); - } - - // We know cap is <=3D `isize::MAX` because `Layout::array` fails = if the resulting byte size - // is greater than `isize::MAX`. So the multiplication by two won'= t overflow. - let new_cap =3D core::cmp::max(cap * 2, len.checked_add(additional= ).ok_or(AllocError)?); - let layout =3D core::alloc::Layout::array::(new_cap).map_err(|_= | AllocError)?; - - let (old_ptr, len, cap) =3D destructure(self); - - // We need to make sure that `ptr` is either NULL or comes from a = previous call to - // `krealloc_aligned`. A `Vec`'s `ptr` value is not guaranteed = to be NULL and might be - // dangling after being created with `Vec::new`. Instead, we can r= ely on `Vec`'s capacity - // to be zero if no memory has been allocated yet. - let ptr =3D if cap =3D=3D 0 { ptr::null_mut() } else { old_ptr }; - - // SAFETY: `ptr` is valid because it's either NULL or comes from a= previous call to - // `krealloc_aligned`. We also verified that the type is not a ZST. - match unsafe { alloc.realloc(ptr.cast(), cap, layout, flags) } { - Ok(ptr) =3D> { - // SAFETY: `ptr` has been reallocated with the layout for = `new_cap` elements. - // `new_cap` is greater than `cap`, so it continues to be = >=3D `len`. - unsafe { rebuild(self, ptr.as_ptr().cast(), len, new_cap) = }; - Ok(()) - } - Err(err) =3D> { - // SAFETY: We are just rebuilding the existing `Vec` with = no changes. - unsafe { rebuild(self, old_ptr, len, cap) }; - Err(err) - } - } - } -} - -#[cfg(not(any(test, testlib)))] -fn destructure(v: &mut Vec) -> (*mut T, usize, usize) { - let mut tmp =3D Vec::new(); - core::mem::swap(&mut tmp, v); - let mut tmp =3D core::mem::ManuallyDrop::new(tmp); - let len =3D tmp.len(); - let cap =3D tmp.capacity(); - (tmp.as_mut_ptr(), len, cap) -} - -/// Rebuilds a `Vec` from a pointer, length, and capacity. -/// -/// # Safety -/// -/// The same as [`Vec::from_raw_parts`]. -#[cfg(not(any(test, testlib)))] -unsafe fn rebuild(v: &mut Vec, ptr: *mut T, len: usize, cap: usize) { - // SAFETY: The safety requirements from this function satisfy those of= `from_raw_parts`. - let mut tmp =3D unsafe { Vec::from_raw_parts(ptr, len, cap) }; - core::mem::swap(&mut tmp, v); -} diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index 0ee3f0d203e2..0836394ddab8 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -14,10 +14,7 @@ #[doc(no_inline)] pub use core::pin::Pin; =20 -pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox, KVec}; - -#[doc(no_inline)] -pub use alloc::vec::Vec; +pub use crate::alloc::{flags::*, KBox, KVec}; =20 #[doc(no_inline)] pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable}; --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C1DF1B5807 for ; Thu, 4 Jul 2024 17:09:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112973; cv=none; b=RZkrtaog/zknyxpDDWIImSJzZErcPR8aL848CbCvXOGW/1qfhHOD+QajsdngyPECkPgwoKuRJPW+BeiBYs3ZqTvsbP+Ow78zrUBruuvxa8edUWN70w6cruguep/IalQw1GCuzOFA39Q03EFt6Reabqq3q7tOQdBDTJg3UMfCGY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112973; c=relaxed/simple; bh=p0HGLvz39MagYLHLnfr1oEDeeFWEr8ljFaHWqx1Mx/4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i9OXwwLvNEdJn6EeoMIl6JekzQcBDvBTI2iWwphVwPwbru9xM7ce4ko0NRHA/ykXdtFI5EZ35pO/GLmlB40buyz7JilyW94X02yCOSocuJS3OEVAw1cXxcOIEO4xqBIfx8SFU72+3DuplP+MvIEEuP/K+CTKVayihLrnpdbBAx4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=jEQ9TaNc; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="jEQ9TaNc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112970; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hONGpcUApGTU4b0CZyPLQC6URu9ThOSHp+V60iJ0Myw=; b=jEQ9TaNc9WovbYag5ENQ0RV26JSy7rCrhsNxf3qcz7JNlGsfPgWmw3qKfXsTr/Nrqdsmj1 3SgEo/ej6Mm50MtuoiW9a5hgKL4Koaf1E3TzxbW0nNwwJm3NFgQqQTvcbrPz5FS7EOLQS1 3PwxLs1o6BrTiQK3BGs0hvIpSm0R8+k= Received: from mail-lf1-f72.google.com (mail-lf1-f72.google.com [209.85.167.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-52-U7SB8OlBPpugV-_32m7raA-1; Thu, 04 Jul 2024 13:09:28 -0400 X-MC-Unique: U7SB8OlBPpugV-_32m7raA-1 Received: by mail-lf1-f72.google.com with SMTP id 2adb3069b0e04-52e9557e312so779836e87.0 for ; Thu, 04 Jul 2024 10:09:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112967; x=1720717767; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hONGpcUApGTU4b0CZyPLQC6URu9ThOSHp+V60iJ0Myw=; b=nYLE0yirBhiPBMAEDR6Vu1TzeiESBx2e5oTHpDTba9iAcxbBAs3hziM/eWSEtVEnDr dKQPD2cS5P4X1DXXP24BZy4LCZpjTfW7z/TNKAF1speQqbFK+HpQ596r6mylSmYl8DIU +Pno6ia6uTdPj5GzgqnNLcmUHo9GVMg59OUa8UHn/CCTLnmy71EQh9V2elcw6PP8yZ6r 40wXW2/PKnMKg3Onu7whAa43SPjSzSnRB134dR3RTBfZ79iuYfBVrVNdX6AkP3SWsb6j PP9ZKoiX/73hKxSui/eb0WMVFel0EtSjU86QcRO06fbMredfDYqlNTQ0ARS3Kv7P5diC rIdA== X-Forwarded-Encrypted: i=1; AJvYcCWwnFyzogO33Q1ImbN60v3V+rmpsygAqA5q18nrluCH+FKLw2LIxtSwUY2Su4y4v8MCEh71W5pNWM3JkbBYRKmQ2o/vjwvy5rQB8Ntw X-Gm-Message-State: AOJu0YxB/qlyEa7K8aCkFLaJ4tIlt66dUesa+4Fssi7QwLBF0jbdOeBN Ei9Q9n/p+Yw5CO6FYuVXuHKl2A8MyXSkl3IHrfD7VlsTOjzk56hJtG0anGpCDaFNsmiUboY/DzY 2N4DknAuEplGx4YdYMK+4JLjMhiphWfsFLrb+FHODBl7r6ig7lIBhX9X22MS/xg== X-Received: by 2002:a05:6512:466:b0:52e:7684:a385 with SMTP id 2adb3069b0e04-52ea06e5329mr1615801e87.52.1720112967319; Thu, 04 Jul 2024 10:09:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHNkphbX7wDz7FOEWh9y4mJC6b0DinFkiDszVdH52GQKQkvJI8z95H8cNwAYSlHgH0L4utJhA== X-Received: by 2002:a05:6512:466:b0:52e:7684:a385 with SMTP id 2adb3069b0e04-52ea06e5329mr1615776e87.52.1720112966875; Thu, 04 Jul 2024 10:09:26 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a1d5100sm31134025e9.4.2024.07.04.10.09.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:26 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 18/20] rust: error: use `core::alloc::LayoutError` Date: Thu, 4 Jul 2024 19:06:46 +0200 Message-ID: <20240704170738.3621-19-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use `core::alloc::LayoutError` instead of `alloc::alloc::LayoutError` in preparation to get rid of Rust's alloc crate. Signed-off-by: Danilo Krummrich --- rust/kernel/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index 55280ae9fe40..20306588bc9e 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -6,7 +6,7 @@ =20 use crate::{alloc::AllocError, str::CStr}; =20 -use alloc::alloc::LayoutError; +use core::alloc::LayoutError; =20 use core::fmt; use core::num::TryFromIntError; --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C79CC1B6A40 for ; Thu, 4 Jul 2024 17:09:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112976; cv=none; b=sRn1AEorrIW2W5pkZwlB6U8UDWBJ3mc9tD5hjwf1M0FH/rZUyr8usg8UxKG4CwQMhI1XafYwwugVuh8a+7FSdpxtCHZJbE8e36Vlqlvwiot6G2lMNVgweZCmt8IKdH1EIla+Mep7sT39QDZfbFB5sZKH6x6pij2DTlGj/1bDl68= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112976; c=relaxed/simple; bh=cvsHu/vJjyAxWbz9+KjaSEX/C/NPmn7UBj8A7wCyhI8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q/BgpUCtkYKXrCTGHBIbHn9mgATerb3lx6K+ONBWTvDsCDQffLJcSodYlowME+WBgyp0xtHoO2I6BL0Zf+dODnIp2tb4Zd5OVuySrEFr+HQTeKlGstpO8PvKd5OYNxJL+lojWgKpcWm4VRWfG3I6KWFmfav8V5aZOAlV/YOr9N4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=F8GPLKmf; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="F8GPLKmf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112974; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9cZ2nwTd2aT7nnbRR2poBKjvcKIKwkNp4GrT7R6rP9E=; b=F8GPLKmf6t6urR4M2L8LbumkpjRzplxh8PkQEqQ1rFM/BfimBgXAkGLU5EFkff6gJizwGO 68f+aZU/k/zknqyO3UahHOMit+btnw4RApU09Kl/xqPoaQF90FKW4X4GzoCoddzsQiXPo1 d//ouKpixxsxZDccaHU3MPH/C8SBj9E= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-527-hqV1gfyINca4OVonAfqUgw-1; Thu, 04 Jul 2024 13:09:32 -0400 X-MC-Unique: hqV1gfyINca4OVonAfqUgw-1 Received: by mail-ej1-f71.google.com with SMTP id a640c23a62f3a-a7535875ab7so252666766b.0 for ; Thu, 04 Jul 2024 10:09:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112971; x=1720717771; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9cZ2nwTd2aT7nnbRR2poBKjvcKIKwkNp4GrT7R6rP9E=; b=cyXU6cJqvslvfLOusCClmWGorBwyEorV0CbVGX5QE4IeEvl7n8Urte1vEm+HqmDhtW laL7lj501huzwsbJlmQiVcO8oEkxYmTbDumP0oRS6HtNdniKa1csa4GeEgKLnpWyMArH 1Rc9eovQaYHKM+3eDcfNY0NHuUku7NE/bR2PXmcBPZBf8YxoEeL6mJWB/IgmgH3qDqMm s5tASoOKhcoCkmnJ8AXvqvkzOLaghdVf7LlY9z+JGh83p4CzpdBa89ZAFDu1VN53LI29 LhMHe2GSFHf0kIXEgJWJ/nN4ZbNXQacbz9iEA3676L0wiYKf0UmQbRe+VwWPuqhfu8E4 gZag== X-Forwarded-Encrypted: i=1; AJvYcCUVG3VXfFyOFY5L3eBZ+JUF/ZDY9hbGUagTNj2AzXAuI8VlcY2hZA5b+KfMlY8cuM0WFf5JV2LCpgrU4nTZm//oMyqGSmgtE2oLDOdL X-Gm-Message-State: AOJu0YwUURn7hkAU1Tp+JQyvA/ECH1FgM/HS6BlAAfdRep8tbp0KOPRp Ey6F5R298915gR5C+AIVa9U4G4k28PU9eOOHgJhm6McRFvYLElCWkwmBGoETUrF7Odp8GHjkEaF e35wGkPCObKfiZESat9Av74cnEbcQeZPedfUdfNp9I1qCYrja4af/edujDNXJEQ== X-Received: by 2002:a17:906:81d4:b0:a6f:dbd1:b493 with SMTP id a640c23a62f3a-a77bd99f2f5mr165474066b.7.1720112971548; Thu, 04 Jul 2024 10:09:31 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF6h/9S2N8JV3CbfoPhW779ld7L7IuWfJVjGNYBSoxtWjpKcgyMQgQsbtRu2lLBX8zQvOkalA== X-Received: by 2002:a17:906:81d4:b0:a6f:dbd1:b493 with SMTP id a640c23a62f3a-a77bd99f2f5mr165471166b.7.1720112971168; Thu, 04 Jul 2024 10:09:31 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a77c0dff4a5sm43957366b.27.2024.07.04.10.09.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:30 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 19/20] rust: str: test: replace `alloc::format` Date: Thu, 4 Jul 2024 19:06:47 +0200 Message-ID: <20240704170738.3621-20-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The current implementation of tests in str.rs use `format!` to format strings for comparison, which, internally, creates a new `String`. In order to prepare for getting rid of Rust's alloc crate, we have to cut this dependency. Instead, we could implement `format!` for `CString`, however `CString` uses `KVec` and hence the kernel allocators, which can't be used for tests run in userspace. Instead, implement `fmt_assert_eq`, which formats strings into a stack allocated buffer for comparison with a `&str`. Signed-off-by: Danilo Krummrich --- rust/kernel/str.rs | 66 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index 0b6ffbade521..539be40754f4 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -523,7 +523,6 @@ macro_rules! c_str { #[cfg(test)] mod tests { use super::*; - use alloc::format; =20 const ALL_ASCII_CHARS: &'static str =3D "\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d= \\x0e\\x0f\ @@ -539,6 +538,33 @@ mod tests { \\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\= \xed\\xee\\xef\ \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\= \xfd\\xfe\\xff"; =20 + fn format_into_buf<'a>(args: fmt::Arguments<'_>, buf: &'a mut [u8]) ->= Result<&'a str, Error> { + let mut f =3D RawFormatter::new(); + f.write_fmt(args)?; + let size =3D f.bytes_written(); + + assert!(buf.len() >=3D size); + + // SAFETY: `buf` has at least a size of `size` bytes and is valid = for writes. + let mut f =3D unsafe { Formatter::from_buffer(buf.as_mut_ptr(), si= ze) }; + f.write_fmt(args)?; + + Ok(core::str::from_utf8(&buf[0..size])?) + } + + macro_rules! fmt_assert_eq { + ($str:expr, $($f:tt)*) =3D> ({ + let mut buf =3D [0_u8; ALL_ASCII_CHARS.len()]; + + let s =3D match format_into_buf(kernel::fmt!($($f)*), &mut buf= ) { + Ok(s) =3D> s, + Err(_) =3D> panic!("Could not format into buffer."), + }; + + assert_eq!($str, s); + }) + } + #[test] fn test_cstr_to_str() { let good_bytes =3D b"\xf0\x9f\xa6\x80\0"; @@ -566,13 +592,13 @@ fn test_cstr_as_str_unchecked() { #[test] fn test_cstr_display() { let hello_world =3D CStr::from_bytes_with_nul(b"hello, world!\0").= unwrap(); - assert_eq!(format!("{}", hello_world), "hello, world!"); + fmt_assert_eq!("hello, world!", "{}", hello_world); let non_printables =3D CStr::from_bytes_with_nul(b"\x01\x09\x0a\0"= ).unwrap(); - assert_eq!(format!("{}", non_printables), "\\x01\\x09\\x0a"); + fmt_assert_eq!("\\x01\\x09\\x0a", "{}", non_printables); let non_ascii =3D CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").un= wrap(); - assert_eq!(format!("{}", non_ascii), "d\\xe9j\\xe0 vu"); + fmt_assert_eq!("d\\xe9j\\xe0 vu", "{}", non_ascii); let good_bytes =3D CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0"= ).unwrap(); - assert_eq!(format!("{}", good_bytes), "\\xf0\\x9f\\xa6\\x80"); + fmt_assert_eq!("\\xf0\\x9f\\xa6\\x80", "{}", good_bytes); } =20 #[test] @@ -583,47 +609,47 @@ fn test_cstr_display_all_bytes() { bytes[i as usize] =3D i.wrapping_add(1); } let cstr =3D CStr::from_bytes_with_nul(&bytes).unwrap(); - assert_eq!(format!("{}", cstr), ALL_ASCII_CHARS); + fmt_assert_eq!(ALL_ASCII_CHARS, "{}", cstr); } =20 #[test] fn test_cstr_debug() { let hello_world =3D CStr::from_bytes_with_nul(b"hello, world!\0").= unwrap(); - assert_eq!(format!("{:?}", hello_world), "\"hello, world!\""); + fmt_assert_eq!("\"hello, world!\"", "{:?}", hello_world); let non_printables =3D CStr::from_bytes_with_nul(b"\x01\x09\x0a\0"= ).unwrap(); - assert_eq!(format!("{:?}", non_printables), "\"\\x01\\x09\\x0a\""); + fmt_assert_eq!("\"\\x01\\x09\\x0a\"", "{:?}", non_printables); let non_ascii =3D CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").un= wrap(); - assert_eq!(format!("{:?}", non_ascii), "\"d\\xe9j\\xe0 vu\""); + fmt_assert_eq!("\"d\\xe9j\\xe0 vu\"", "{:?}", non_ascii); let good_bytes =3D CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0"= ).unwrap(); - assert_eq!(format!("{:?}", good_bytes), "\"\\xf0\\x9f\\xa6\\x80\""= ); + fmt_assert_eq!("\"\\xf0\\x9f\\xa6\\x80\"", "{:?}", good_bytes); } =20 #[test] fn test_bstr_display() { let hello_world =3D BStr::from_bytes(b"hello, world!"); - assert_eq!(format!("{}", hello_world), "hello, world!"); + fmt_assert_eq!("hello, world!", "{}", hello_world); let escapes =3D BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); - assert_eq!(format!("{}", escapes), "_\\t_\\n_\\r_\\_'_\"_"); + fmt_assert_eq!("_\\t_\\n_\\r_\\_'_\"_", "{}", escapes); let others =3D BStr::from_bytes(b"\x01"); - assert_eq!(format!("{}", others), "\\x01"); + fmt_assert_eq!("\\x01", "{}", others); let non_ascii =3D BStr::from_bytes(b"d\xe9j\xe0 vu"); - assert_eq!(format!("{}", non_ascii), "d\\xe9j\\xe0 vu"); + fmt_assert_eq!("d\\xe9j\\xe0 vu", "{}", non_ascii); let good_bytes =3D BStr::from_bytes(b"\xf0\x9f\xa6\x80"); - assert_eq!(format!("{}", good_bytes), "\\xf0\\x9f\\xa6\\x80"); + fmt_assert_eq!("\\xf0\\x9f\\xa6\\x80", "{}", good_bytes); } =20 #[test] fn test_bstr_debug() { let hello_world =3D BStr::from_bytes(b"hello, world!"); - assert_eq!(format!("{:?}", hello_world), "\"hello, world!\""); + fmt_assert_eq!("\"hello, world!\"", "{:?}", hello_world); let escapes =3D BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); - assert_eq!(format!("{:?}", escapes), "\"_\\t_\\n_\\r_\\\\_'_\\\"_\= ""); + fmt_assert_eq!("\"_\\t_\\n_\\r_\\\\_'_\\\"_\"", "{:?}", escapes); let others =3D BStr::from_bytes(b"\x01"); - assert_eq!(format!("{:?}", others), "\"\\x01\""); + fmt_assert_eq!("\"\\x01\"", "{:?}", others); let non_ascii =3D BStr::from_bytes(b"d\xe9j\xe0 vu"); - assert_eq!(format!("{:?}", non_ascii), "\"d\\xe9j\\xe0 vu\""); + fmt_assert_eq!("\"d\\xe9j\\xe0 vu\"", "{:?}", non_ascii); let good_bytes =3D BStr::from_bytes(b"\xf0\x9f\xa6\x80"); - assert_eq!(format!("{:?}", good_bytes), "\"\\xf0\\x9f\\xa6\\x80\""= ); + fmt_assert_eq!("\"\\xf0\\x9f\\xa6\\x80\"", "{:?}", good_bytes); } } =20 --=20 2.45.2 From nobody Sat Feb 7 10:16:24 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E614E1B6A4F for ; Thu, 4 Jul 2024 17:09:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112983; cv=none; b=bU4BhvUrUHq+5bZGrEeviRK0QIyUpRIBE1NZSxC4Xrlx07JtPW7+73BID/tE3ee9SJkJMbBQfhVYr0nUQboRtozKNTGuhglMbTqxJoJ1aEASo02lik/rgqGEhJxQT6nsI58IHbB1un1nk4n7J/5+lNuhenOD84MVlvFcOCpIaG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720112983; c=relaxed/simple; bh=bsriniNdpX6h5/yDL9FxdgsDYScO2q5NtPU4YXaim9E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MZUxAhifVlAzLDhc0lLnId7rRSaNeh9PIW1c+UFWD9vOep3aqOAexEKmm9+86KsBOlGpVFdVBsxJHS9T8LkGz8DL4zu7E4k6PAUCQGhY26gPAgcyKnEmJ5UTMiBAinAmMbXHxWXtU6wv25pXg56zipmh0pB/TxaBh06WfSutw9Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=axvdwXMO; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="axvdwXMO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720112980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xYIznhyjauFiWydkaqs7Zncv4tbDnSQ032ir9VqSIpY=; b=axvdwXMOnv1nEruCYI1ZxVT+l94kd+piPpLK39dH0QcVXMShjCzchbV++v3AEDBJlh47ab mq7Sdwnwl/5MNgr8iuyrdne+Btm3wHl2BIuYeYnu2vyZdkf39O94mr/9XE8rlAqjKMnRYl 4CYpMs6mbRF5Y2HpoJ5kjJmnhBklNlE= Received: from mail-lf1-f71.google.com (mail-lf1-f71.google.com [209.85.167.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-490-6QiDWvzAOs2Su_xAdoNmMA-1; Thu, 04 Jul 2024 13:09:39 -0400 X-MC-Unique: 6QiDWvzAOs2Su_xAdoNmMA-1 Received: by mail-lf1-f71.google.com with SMTP id 2adb3069b0e04-52ea3c7dfdcso150816e87.3 for ; Thu, 04 Jul 2024 10:09:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720112977; x=1720717777; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xYIznhyjauFiWydkaqs7Zncv4tbDnSQ032ir9VqSIpY=; b=J4eyjTALnQywnYuXcBTvqKT9nHA2iNxg/vL/gx9xKhQESDKowIxvzqy08kt0tkpQfQ 2BfUy7EXX3s7C+2QkspFQdhoYCtAgEJTflVqAK5Owh+eLi5pHnANUvevJ/Ylr3tZFxjX aVIs8H0R+PlqPjVLAQUMIu6v6f1YQaqJ5KES5RpHM9wJO1J8+nGQzAYwR8gSongQLsov A24AWybji0YrA3706VCr30Zk9oGqgNu3AzNGtiQNUEGwiDUrvT0HMsKB/6V2OzhaaR/f slYnv0Yd3zScGBYpzI4rb87s4VeRqEFh0fTp0C8pYNHqgWwmNQaiBiQvNTlHNtnINtEv hWrQ== X-Forwarded-Encrypted: i=1; AJvYcCVsO3Ka3ttPshnSdUDoVZ8XRcclX3j7FcI+Lr12dtSUGqm7tbJ9rrCGqubB1MSyVbPYSygBR3eWAA+4+4vUh3VZhfF/RBexFdXrvuEf X-Gm-Message-State: AOJu0YxeToKNxqDNxRKj8d2c6/P/XlxTyYfIJtzeOqMFdTfxCiAySFnS gERct6rM7Hg1x9aOolVUw0AWsEqoTSrjARSvoUMaZ9G15LP9JFfOZbTrYBWCxm1yoHn0A9Ti9vL 5V/l13vZF6F7c6+tf+LBY/9Ce5823Z3Ra+BCmu491B9j8old0QAAWB7q/QKxL/A== X-Received: by 2002:ac2:5b0e:0:b0:52e:9fda:f18a with SMTP id 2adb3069b0e04-52ea06cbe66mr1511996e87.44.1720112977587; Thu, 04 Jul 2024 10:09:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFX6ONW2CA5btbaQ6QdRa6JyXEnGgf0cFnmiUOxEATBml1XRR3xBl1VWyuUT+INBga4rn8Mvw== X-Received: by 2002:ac2:5b0e:0:b0:52e:9fda:f18a with SMTP id 2adb3069b0e04-52ea06cbe66mr1511908e87.44.1720112975258; Thu, 04 Jul 2024 10:09:35 -0700 (PDT) Received: from cassiopeiae.. ([2a02:810d:4b3f:ee94:642:1aff:fe31:a19f]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4264a283577sm31189545e9.44.2024.07.04.10.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jul 2024 10:09:34 -0700 (PDT) From: Danilo Krummrich To: 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, aliceryhl@google.com Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@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, Danilo Krummrich Subject: [PATCH 20/20] kbuild: rust: remove the `alloc` crate Date: Thu, 4 Jul 2024 19:06:48 +0200 Message-ID: <20240704170738.3621-21-dakr@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240704170738.3621-1-dakr@redhat.com> References: <20240704170738.3621-1-dakr@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that we have our own `Allocator`, `KBox` and `KVec` we can remove Rust's `alloc` crate and the corresponding unstable features. Signed-off-by: Danilo Krummrich --- rust/Makefile | 44 ++++++++++-------------------------------- rust/exports.c | 1 - scripts/Makefile.build | 7 +------ 3 files changed, 11 insertions(+), 41 deletions(-) diff --git a/rust/Makefile b/rust/Makefile index f70d5e244fee..409be08ad09a 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -15,9 +15,8 @@ always-$(CONFIG_RUST) +=3D libmacros.so no-clean-files +=3D libmacros.so =20 always-$(CONFIG_RUST) +=3D bindings/bindings_generated.rs bindings/binding= s_helpers_generated.rs -obj-$(CONFIG_RUST) +=3D alloc.o bindings.o kernel.o -always-$(CONFIG_RUST) +=3D exports_alloc_generated.h exports_bindings_gene= rated.h \ - exports_kernel_generated.h +obj-$(CONFIG_RUST) +=3D bindings.o kernel.o +always-$(CONFIG_RUST) +=3D exports_bindings_generated.h exports_kernel_gen= erated.h =20 always-$(CONFIG_RUST) +=3D uapi/uapi_generated.rs obj-$(CONFIG_RUST) +=3D uapi.o @@ -60,11 +59,6 @@ endif core-cfgs =3D \ --cfg no_fp_fmt_parse =20 -alloc-cfgs =3D \ - --cfg no_global_oom_handling \ - --cfg no_rc \ - --cfg no_sync - quiet_cmd_rustdoc =3D RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc =3D \ OBJTREE=3D$(abspath $(objtree)) \ @@ -87,7 +81,7 @@ quiet_cmd_rustdoc =3D RUSTDOC $(if $(rustdoc_host),H, ) $< # command-like flags to solve the issue. Meanwhile, we use the non-custom = case # and then retouch the generated files. rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ - rustdoc-alloc rustdoc-kernel + rustdoc-kernel $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.= files/ $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/sta= tic.files/ $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed = -Ei \ @@ -111,20 +105,11 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE +$(call if_changed,rustdoc) =20 -# We need to allow `rustdoc::broken_intra_doc_links` because some -# `no_global_oom_handling` functions refer to non-`no_global_oom_handling` -# functions. Ideally `rustdoc` would have a way to distinguish broken links -# due to things that are "configured out" vs. entirely non-existing ones. -rustdoc-alloc: private rustc_target_flags =3D $(alloc-cfgs) \ - -Arustdoc::broken_intra_doc_links -rustdoc-alloc: $(RUST_LIB_SRC)/alloc/src/lib.rs rustdoc-core rustdoc-compi= ler_builtins FORCE - +$(call if_changed,rustdoc) - -rustdoc-kernel: private rustc_target_flags =3D --extern alloc \ +rustdoc-kernel: private rustc_target_flags =3D \ --extern build_error --extern macros=3D$(objtree)/$(obj)/libmacros.so \ --extern bindings --extern uapi rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ - rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \ + rustdoc-compiler_builtins $(obj)/libmacros.so \ $(obj)/bindings.o FORCE +$(call if_changed,rustdoc) =20 @@ -169,7 +154,7 @@ quiet_cmd_rustdoc_test_kernel =3D RUSTDOC TK $< mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ OBJTREE=3D$(abspath $(objtree)) \ $(RUSTDOC) --test $(rust_flags) \ - -L$(objtree)/$(obj) --extern alloc --extern kernel \ + -L$(objtree)/$(obj) --extern kernel \ --extern build_error --extern macros \ --extern bindings --extern uapi \ --no-run --crate-name kernel -Zunstable-options \ @@ -251,7 +236,7 @@ rusttest-macros: $(src)/macros/lib.rs rusttest-prepare = FORCE +$(call if_changed,rustc_test) +$(call if_changed,rustdoc_test) =20 -rusttest-kernel: private rustc_target_flags =3D --extern alloc \ +rusttest-kernel: private rustc_target_flags =3D \ --extern build_error --extern macros --extern bindings --extern uapi rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ @@ -364,9 +349,6 @@ quiet_cmd_exports =3D EXPORTS $@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(call if_changed,exports) =20 -$(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE - $(call if_changed,exports) - $(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE $(call if_changed,exports) =20 @@ -402,7 +384,7 @@ quiet_cmd_rustc_library =3D $(if $(skip_clippy),RUSTC,$= (RUSTC_OR_CLIPPY_QUIET)) L =20 rust-analyzer: $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ - --cfgs=3D'core=3D$(core-cfgs)' --cfgs=3D'alloc=3D$(alloc-cfgs)' \ + --cfgs=3D'core=3D$(core-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json @@ -434,12 +416,6 @@ $(obj)/compiler_builtins.o: private rustc_objcopy =3D = -w -W '__*' $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE +$(call if_changed_dep,rustc_library) =20 -$(obj)/alloc.o: private skip_clippy =3D 1 -$(obj)/alloc.o: private skip_flags =3D -Dunreachable_pub -$(obj)/alloc.o: private rustc_target_flags =3D $(alloc-cfgs) -$(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.= o FORCE - +$(call if_changed_dep,rustc_library) - $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FOR= CE +$(call if_changed_dep,rustc_library) =20 @@ -454,9 +430,9 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \ $(obj)/uapi/uapi_generated.rs FORCE +$(call if_changed_dep,rustc_library) =20 -$(obj)/kernel.o: private rustc_target_flags =3D --extern alloc \ +$(obj)/kernel.o: private rustc_target_flags =3D \ --extern build_error --extern macros --extern bindings --extern uapi -$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ +$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE +$(call if_changed_dep,rustc_library) =20 diff --git a/rust/exports.c b/rust/exports.c index 3803c21d1403..1b870e8e83ea 100644 --- a/rust/exports.c +++ b/rust/exports.c @@ -16,7 +16,6 @@ #define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym) =20 #include "exports_core_generated.h" -#include "exports_alloc_generated.h" #include "exports_bindings_generated.h" #include "exports_kernel_generated.h" =20 diff --git a/scripts/Makefile.build b/scripts/Makefile.build index efacca63c897..7e7b6b3d5bb9 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -262,18 +262,13 @@ $(obj)/%.lst: $(obj)/%.c FORCE =20 # Compile Rust sources (.rs) # ------------------------------------------------------------------------= --- - -rust_allowed_features :=3D new_uninit - # `--out-dir` is required to avoid temporaries being created by `rustc` in= the # current working directory, which may be not accessible in the out-of-tree # modules case. rust_common_cmd =3D \ RUST_MODFILE=3D$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ - -Zallow-features=3D$(rust_allowed_features) \ -Zcrate-attr=3Dno_std \ - -Zcrate-attr=3D'feature($(rust_allowed_features))' \ - -Zunstable-options --extern force:alloc --extern kernel \ + -Zunstable-options --extern kernel \ --crate-type rlib -L $(objtree)/rust/ \ --crate-name $(basename $(notdir $@)) \ --sysroot=3D/dev/null \ --=20 2.45.2