From nobody Sun Oct 5 05:28:59 2025 Received: from mailrelay-egress16.pub.mailoutpod3-cph3.one.com (mailrelay-egress16.pub.mailoutpod3-cph3.one.com [46.30.212.3]) (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 15E7B78F36 for ; Fri, 8 Aug 2025 15:07:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.30.212.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754665652; cv=none; b=A5fFXP2zJAmySFCdYXgt/P7DFBBdAEtspWScSP3YFpdOKeVT2ADUZsO5tnG7Or81Ku7+mUn2wQQ2I8svtfRMhW27w9kpeVB/SCwvFuLnyIcG1PTMauaWcoicEmQeGshEiZlxypUf8w/7Ze4gv2355gdtx+sVPBf2Xu9KTZf3i2s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754665652; c=relaxed/simple; bh=qUmgf6BTlS6Tq4v69ENyws+aLYifYqV93BeLmR/roZ8=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=CKBvfbsB8M79IhdNkGmZocKHNR2YYsPU7uMWPYoPAw1AbZUBFihQtyeu/donlvsx8tUXYxDMYwazcFfEpM+F4RFfEcsJ9ZJbfKNJ1pcd67rE9gX8c+35oxTPTU50OMIObIcxQe/jf3qCAC/+zYnYn3K7msC3Dxt7u7NjJxNLl8Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=konsulko.se; spf=none smtp.mailfrom=konsulko.se; dkim=pass (2048-bit key) header.d=konsulko.se header.i=@konsulko.se header.b=Lc0mbJQN; dkim=permerror (0-bit key) header.d=konsulko.se header.i=@konsulko.se header.b=Ptx9D/MD; arc=none smtp.client-ip=46.30.212.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=konsulko.se Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=konsulko.se Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=konsulko.se header.i=@konsulko.se header.b="Lc0mbJQN"; dkim=permerror (0-bit key) header.d=konsulko.se header.i=@konsulko.se header.b="Ptx9D/MD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1754665640; x=1755270440; d=konsulko.se; s=rsa1; h=content-transfer-encoding:mime-version:message-id:date:subject:cc:to:from: from; bh=uiWgxunv6QTnvQv+xN5Ogh6F+viAfMdu93dlj/u2MPI=; b=Lc0mbJQNoHJGieFCGZWvHI+38xxzNzO0raBpgPim4lpzZtA6mOeP07Y/qiLyV79Y0CuFF/PhE4EZF 7puIxpClse3Zl5y1QS3tNupfRBHi2jM1l6ryiWuvUmhguxiPr7bZvXv0ckR5fyUsMexkQvpV87v39n VRJvX49hfChzedME0GCWbaMgsNSHBCce21mI3fyR8sloM0Y27MKSQRhAOaywAzFF0xaEN99yI9RFZZ KaxkAubjn5klV+3tsQQXhKls3+j/6K3wNgsJg6djHaf9stvN/0TKfHrY+tDXU+N78Urc8AByDfGohs OYw6f/si0mtUGXkZbWDQZ8Bz2BPTdXw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1754665640; x=1755270440; d=konsulko.se; s=ed1; h=content-transfer-encoding:mime-version:message-id:date:subject:cc:to:from: from; bh=uiWgxunv6QTnvQv+xN5Ogh6F+viAfMdu93dlj/u2MPI=; b=Ptx9D/MDVsaJXpWBQSzqjU4cxMjsfRNvc64v9H75xqHvCBh/K4MKhihgtfRncL4xsWN82l4G2wqVR 4JY5Kp3Dg== X-HalOne-ID: 607fa9b2-7469-11f0-9500-85eb291bc831 Received: from localhost.localdomain (host-95-203-16-218.mobileonline.telia.com [95.203.16.218]) by mailrelay5.pub.mailoutpod2-cph3.one.com (Halon) with ESMTPSA id 607fa9b2-7469-11f0-9500-85eb291bc831; Fri, 08 Aug 2025 15:07:19 +0000 (UTC) From: Vitaly Wool To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Uladzislau Rezki , Danilo Krummrich , Alice Ryhl , Vlastimil Babka , Lorenzo Stoakes , "Liam R . Howlett" , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , Bjorn Roy Baron , Benno Lossin , Andreas Hindborg , Trevor Gross , Vitaly Wool Subject: [PATCH] rust: alloc: implement Box::pin_slice() Date: Fri, 8 Aug 2025 17:07:16 +0200 Message-Id: <20250808150716.2479375-1-vitaly.wool@konsulko.se> X-Mailer: git-send-email 2.39.2 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" From: Alice Ryhl Add a new constructor to Box to facilitate Box creation from a pinned slice of elements. This allows to efficiently allocate memory for e.g. slices of structrures containing spinlocks or mutexes. Such slices may be used in kmemcache like or zpool API implementations. Signed-off-by: Alice Ryhl Signed-off-by: Vitaly Wool --- This patch supersedes "rust: extend kbox with a new constructor" posted a day earlier. rust/kernel/alloc/kbox.rs | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 1fef9beb57c8..f0be307f7242 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -290,6 +290,67 @@ pub fn pin(x: T, flags: Flags) -> Result= >, AllocError> Ok(Self::new(x, flags)?.into()) } =20 + /// Construct a pinned slice of elements `Pin>`. + /// + /// This is a convenient means for creation of e.g. slices of structru= res containing spinlocks + /// or mutexes. + /// + /// # Examples + /// + /// ``` + /// #[pin_data] + /// struct Example { + /// c: u32, + /// #[pin] + /// d: SpinLock, + /// } + /// + /// impl Example { + /// fn new() -> impl PinInit { + /// pin_init!(Self { + /// c: 10, + /// d <- new_spinlock!(Inner { a: 20, b: 30 }), + /// }) + /// } + /// } + /// // Allocate a boxed slice of 10 `Example`s. + /// let s =3D KBox::pin_slice( + /// | _i | Example::new(), + /// 10, + /// GFP_KERNEL + /// )?; + /// assert_eq!(s[5].c, 10); + /// assert_eq!(s[3].d.lock().a, 20), + /// ``` + pub fn pin_slice( + mut init: Func, + len: usize, + flags: Flags, + ) -> Result>, E> + where + Func: FnMut(usize) -> Item, + Item: PinInit, + E: From, + { + let mut buffer =3D super::Vec::::with_capacity(len, flags)?; + for i in 0..len { + let ptr =3D buffer.spare_capacity_mut().as_mut_ptr().cast(); + // SAFETY: + // - `ptr` is a valid pointer to uninitialized memory. + // - `ptr` is not used if an error is returned. + // - `ptr` won't be moved until it is dropped, i.e. it is pinn= ed. + unsafe { init(i).__pinned_init(ptr)? }; + // SAFETY: + // - `i + 1 <=3D len` =3D> we don't exceed the capacity + // - this new value is initialized + unsafe { buffer.inc_len(1) }; + } + let (ptr, _, _) =3D buffer.into_raw_parts(); + let slice =3D core::ptr::slice_from_raw_parts_mut(ptr, len); + // SAFETY: `slice` is not a NULL pointer because it is a valid poi= nter to [T] + Ok(Pin::from(unsafe { Box::from_raw(slice) })) + } + /// Convert a [`Box`] to a [`Pin>`]. If `T` does not imp= lement /// [`Unpin`], then `x` will be pinned in memory and can't be moved. pub fn into_pin(this: Self) -> Pin { --=20 2.39.2