From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (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 211DD4642D for ; Wed, 30 Jul 2025 03:59:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753847979; cv=none; b=dWJOJbZal3jhR43F8auV9HFGt6pd0JmniqsUmXMYQn3dCvLBeAPAQaEKCZfTt2QBaCEaBtwe5ySkfZGo6VKMwc+vcJi80wWQ13gBlKiHbNQW5LkP66lZ1hMy8Do1rPawtmcyMjwdDatkABtKiUhKCAmJGvBX1aQEpAOWc9fWOZY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753847979; c=relaxed/simple; bh=2Vx+OVkIDNsjIzjIyltCRx3+scY2So6yx83lQF+SMmM=; h=MIME-Version:Date:Content-Type:From:Message-ID:Subject:To:Cc: In-Reply-To:References; b=gz7kkbZPDYMOtfADVNwjcOR4PHX8M58nNrLG6iQnlVtJxvwXEmzlduO8CM507U/ARU6u4IhSQkd2umyiAyAj0frQbBp2O2F3l4svgkKP10xoBekxp74UhMaaAtDMyRvF/4xevWF55KCZ22FY6xYatzjhUkp3v65yBZkzQS0XeWo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=qsHaJBmx; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="qsHaJBmx" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753847965; 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=dlYZtGZVyCi4PinlFv9/1yDi5aJSz0ey8B3bkRTTyFE=; b=qsHaJBmxhNoF2T/EbYommxMEZ+IY8yJCw8kJsFysiXkkO3j20a7sw4TMtISwGuvcFZD7d0 Ebw72OWXpqSTHNgnAagiVcvB/ME2a2qm/+R3vWuEdNHeV8CS8F7kY7zh0V4xJ+/CDY1Q4i vf1D5ZIRZApKPrjt2AD7oNItYUeK2f8= Date: Wed, 30 Jul 2025 03:59:21 +0000 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: "Hui Zhu" Message-ID: TLS-Required: No Subject: Re: [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees To: "Danilo Krummrich" Cc: "Lorenzo Stoakes" , "Vlastimil Babka" , "Liam R . Howlett" , "Uladzislau Rezki" , "Miguel Ojeda" , "Alex Gaynor" , "Boqun Feng" , "Gary Guo" , bjorn3_gh@protonmail.com, "Benno Lossin" , "Andreas Hindborg" , "Alice Ryhl" , "Trevor Gross" , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, "Hui Zhu" , "Geliang Tang" , "Andrew Morton" , vitaly.wool@konsulko.se In-Reply-To: References: X-Migadu-Flow: FLOW_OUT 2025=E5=B9=B47=E6=9C=8825=E6=97=A5 18:02, "Danilo Krummrich" =E5=86=99=E5=88=B0: >=20 >=20(Cc: Andrew) >=20 >=20On Fri Jul 25, 2025 at 11:50 AM CEST, Danilo Krummrich wrote: >=20 >=20>=20 >=20> On Fri Jul 25, 2025 at 9:02 AM CEST, Hui Zhu wrote: > >=20 >=20> >=20 >=20> > From: Hui Zhu > > >=20 >=20> > Add comprehensive tests to verify correct alignment handling in = Rust > > > allocator wrappers. The tests validate: > > >=20 >=20> > That kmalloc respects both standard (128-byte) and page-size > > > (8192-byte) alignments when allocating structs with explicit align= ment > > > attributes. > > >=20 >=20> > That vmalloc correctly handles standard alignments but intention= ally > > > rejects allocations requiring alignments larger than its capabilit= ies. > > >=20 >=20> > That kvmalloc mirrors vmalloc's constraints, accepting standard > > > alignments but rejecting excessive alignment requirements. > > >=20 >=20> > The test infrastructure uses specialized aligned structs (Blob a= nd > > > LargeAlignBlob) and a test harness (TestAlign) to validate pointer > > > alignment through different allocation paths. This ensures our Rus= t > > > allocators correctly propagate kernel allocation constraints. > > >=20 >=20> > Co-developed-by: Geliang Tang > > > Signed-off-by: Geliang Tang > > > Signed-off-by: Hui Zhu > > >=20 >=20> Thanks, this looks good. I think it would be good to rebase onto [= 1], since it > > will likely land in the same cycle. Additionally, two nits below. > >=20 >=20Please also Cc: Andrew for subsequent submissions, since this will, d= ue to the > interaction with [1] likely go through his tree. >=20 >=20>=20 >=20> As a follow-up we could also test alignment in the context of > > Allocator::realloc(), i.e. when growing and shrinking buffers or req= uesting a > > different NUMA node. > >=20 >=20> [1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.w= ool@konsulko.se/ > >=20 >=20> >=20 >=20> > --- > > > rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++= ++++ > > > 1 file changed, 58 insertions(+) > > >=20 >=20> > diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/= allocator.rs > > > index aa2dfa9dca4c..bcc916240f11 100644 > > > --- a/rust/kernel/alloc/allocator.rs > > > +++ b/rust/kernel/alloc/allocator.rs > > > @@ -187,3 +187,61 @@ unsafe fn realloc( > > > unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flag= s) } > > > } > > > } > > > + > > > +#[macros::kunit_tests(rust_allocator_kunit)] > > > +mod tests { > > > + use super::*; > > > + use core::mem::MaybeUninit; > > > + use kernel::prelude::*; > > > + > > >=20 >=20> --8<-- > >=20 >=20> >=20 >=20> > + const TEST_SIZE: usize =3D 1024; > > > + const TEST_LARGE_ALIGN_SIZE: usize =3D kernel::page::PAGE_SIZE *= 4; > > > + > > > + // These two structs are used to test allocating aligned memory. > > > + // they don't need to be accessed, so they're marked as dead_cod= e. > > > + #[allow(dead_code)] > > >=20 >=20> This should be #[expect(dead_code)]. > >=20 >=20> >=20 >=20> > + #[repr(align(128))] > > > + struct Blob([u8; TEST_SIZE]); > > > + #[allow(dead_code)] > > > + #[repr(align(8192))] > > > + struct LargeAlignBlob([u8; TEST_LARGE_ALIGN_SIZE]); > > > + > > > + struct TestAlign(Box, A>); > > > + impl TestAlign { > > > + fn new() -> Result { > > > + Ok(Self(Box::<_, A>::new_uninit(GFP_KERNEL)?)) > > > + } > > > + > > > + fn alignment_valid(&self, align: usize) -> bool { > > > + assert!(align.is_power_of_two()); > > > + > > > + let addr =3D self.0.as_ptr() as usize; > > > + if addr & (align - 1) !=3D 0 { > > > + false > > > + } else { > > > + true > > > + } > > >=20 >=20> This can just be > >=20 >=20> addr & (align - 1) =3D=3D 0 > >=20 >=20> instead of the conditional clause. > >=20 >=20> >=20 >=20> > + } > > > + } > > >=20 >=20> We could move all the above into test_alignment() given that it's = likely only > > needed from there. > >=20 >=20> >=20 Hi=20Danilo, Thanks! I sent v6 version that rebased on [1]. Best, Hui [1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.wool@kon= sulko.se/ > > > + > > > + #[test] > > > + fn test_alignment() -> Result<()> { > > > + let ta =3D TestAlign::::new()?; > > > + assert!(ta.alignment_valid(128)); > > > + > > > + let ta =3D TestAlign::::new()?; > > > + assert!(ta.alignment_valid(8192)); > > > + > > > + let ta =3D TestAlign::::new()?; > > > + assert!(ta.alignment_valid(128)); > > > + > > > + assert!(TestAlign::::new().is_err()); > > > + > > > + let ta =3D TestAlign::::new()?; > > > + assert!(ta.alignment_valid(128)); > > > + > > > + assert!(TestAlign::::new().is_err()); > > > + > > > + Ok(()) > > > + } > > > +} > > > --=20 >=20> > 2.43.0 > > > > > >