From nobody Tue Dec 2 00:25:31 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E1AFF3242A2 for ; Tue, 25 Nov 2025 13:59:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764079199; cv=none; b=O1feu46h+WvLgtWF0/djwGDIxg1V6Op6u+fvZeb91vVmIhj5UQy2jIqEVbodl4Sq8SYZ5bTJlS2ZwVRK4e39NoQWr3BwsJLqJKixeMDckcsIrO1ERUtz38tXeAfDnPMvGizeO3tmDcWDBeH9GE6OXyIjJmoke+4zJ9Xti3X+Faw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764079199; c=relaxed/simple; bh=emQPdhup99Z5QtiURk30Lj0zFxcNy6czk/mQFRFY1Ec=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KJFzqt+Agj8qph+InC/dPCIqqlxy1ZslVvvFK4sbJaCJHjFYgSEB+zFClwBuzvO84NRNFZCZsunJ2A1SCsg+bl4/2cL/W7ZoOzIE9zGt5h6Ad/QgP83/aINuUh6c5e4ZKSBXSAxrR+UppdxOd/0tugriRvQov6+W4cuG/3Pxceo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=pMPc514y; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pMPc514y" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-477cabba65dso23180925e9.2 for ; Tue, 25 Nov 2025 05:59:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764079195; x=1764683995; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=chXXKrD+EO5miwbK6PlKXaTfuoU30ukfdCueJLsRgKk=; b=pMPc514y/accauwuPYSqNkZ8tbYH9ESbnXg8KvKQRFkcTTO0Wy7BmDtuErWjbKajMn ODENe/JhQcjyBtTf03PnwumXhDIvPf1vPkmCQ7tYzgqqWs3NvBlF8qkGUJUo7Ib6A5w2 NNRQpkzstPuFlStvSdaRtVsnIttYlrwLh2DZBP3GU1UxSt8sfubLgZ0BPUcw5EzFh+NZ Px2/u7eACknsqU9mdfqwAfhyKsadneb7thLHYpvyBbAn/5W+DPWamlmNCZsOrBdftSC1 FYt7TEm0HAzsy7F8oCmYqEhDDtTyhSuZgNkEObkxt33vVH31fHBUE/XAPubeRYljlL1Z YDmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764079195; x=1764683995; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=chXXKrD+EO5miwbK6PlKXaTfuoU30ukfdCueJLsRgKk=; b=ZqGpx5jKCS3ZGVX+k+hoygIPoIAzO1QUOHqaS2d/YPT4E2mEkDGmnWwOemyP4fAdP+ XqdWevba3mv/d7YbZcBm2mnCOaeWGYS56D2esRuYpMfON3N4650ZkOZlON7NQGB+bt/y RbdOfEYN8ib2IAZhqLmf61Nnwn0n9+v0zt8pijT0zT3HQhSl0iL7HSzcg3MCGfkjfOb8 WZEH9yaJIb9wot36ONoYTCu7NGHGqDCtnUHkSxiZZUToYU+S1HHS+x40HdViHCKohgeZ UlPpRhmsNPN5tH0Md07Lpaakc+QKYtUcNqRcJ93Dg36EfmtF8vH/JgwQWKHf3PzOwOzF 8oOQ== X-Forwarded-Encrypted: i=1; AJvYcCWIn7hBMDhqfwEMIdxXzy6+m3eDsneoDyXoXCcJVUxOwK+GFVMo8Sn4qRHr53WNhz5/kMKEjlNviL4jpHs=@vger.kernel.org X-Gm-Message-State: AOJu0YyNTay7G5JZ024sqGCpZ9ldNkDhDRFaY/nzVGo3IjxG4c9ykUZO qVLIyNEh5drEr1mdtFHt/9oHqJ4ra9bFkqnnIq/jA0kXE99ZHH7a0mAkBSnrp9TdhHzsfsIgn1z RE9CmwDRgCcYrQQNYDQ== X-Google-Smtp-Source: AGHT+IGRFXXkiHfta8PSnKNzjAC2VJBxGSZWUgFyXbv+BxfdZofY3oqG0yTSaodz9j8ihSokENMBvq0kn8NmCsI= X-Received: from wmht12.prod.google.com ([2002:a05:600c:41cc:b0:477:9f68:c324]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:154c:b0:477:7b16:5f88 with SMTP id 5b1f17b1804b1-477c0165a5cmr146798485e9.6.1764079195375; Tue, 25 Nov 2025 05:59:55 -0800 (PST) Date: Tue, 25 Nov 2025 13:59:37 +0000 In-Reply-To: <20251125-binder-bitmap-v6-0-dedaf1d05a98@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251125-binder-bitmap-v6-0-dedaf1d05a98@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=9078; i=aliceryhl@google.com; h=from:subject:message-id; bh=emQPdhup99Z5QtiURk30Lj0zFxcNy6czk/mQFRFY1Ec=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBpJbZYFGwaU4GbCDXqBbs3FZ6Xabk52Z9GLWkzp z424Dg+9aWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaSW2WAAKCRAEWL7uWMY5 RrTqD/4iDROrp6gmLNwpy1aWZjr/JZps3FQvutW7W2LSYcMrtWW1MkIuJ8Htxf+ve0GnMC4ibd3 4kQPbyfATUR748Y3u95t0akpkkVjicxlrEuq5FbYgN3DBTOoylLtV2hLuYF1qTV1zzNImGbsp83 uxiqVFPN4NeF76Eg0JFfLay62UPWDVXKu6Ona+Wy6bL7gqldojVggQMkWbyjPLRqkieR/JeNXY3 zBK8bOeAjwX+/WK6cCN9WkwvSHIv3z5kzJoBSCBE4MRV1VbG8qsw4K5A4oz7qduVFBC4Li43IKz EVyhuW0pRNC9w8iMWSPPaDTFJKKKF4N393FzKrEOuygS18VM0JF43bXtJPRnRY3F7Mc1IVkw60X s/So/jFxY62vqKF29MX6826V8haRTmMtGg0tvr6Gj1ieePOxKD8dwAxli+/+I9ygAiSw8KXGmjL 4WxeOSYeyCgs/2nINTrzsDG/r0WqFKirYgU27Vmcb8rmOzN1YfRShi0xNI4XfhrF5TWgCenA0Zu 6SohPlBl7npMSS/8K0SohcAfNQ/4wTO62CsPAOYstYJqpjNvr9OjZimUEAP9iHMdh/rLWlyhWYb /IovPGg6WnfHp5cZI5pyteQV0o8Fwii5gzu5Ou/GW+WVxuRkLbzC0cHTfMAvmgjC/LsOVrqw0f5 YS8rxo+0rKF3j3A== X-Mailer: b4 0.14.2 Message-ID: <20251125-binder-bitmap-v6-1-dedaf1d05a98@google.com> Subject: [PATCH v6 1/6] rust: bitmap: add MAX_LEN and MAX_INLINE_LEN constants From: Alice Ryhl To: Greg Kroah-Hartman , Yury Norov Cc: "=?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Christian Brauner , Carlos Llamas , Suren Baghdasaryan , Burak Emir , Miguel Ojeda , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable To avoid hard-coding these values in drivers, define constants for them that drivers can reference. Also, update all instances in bitmap.rs and id_pool.rs that use these values to use the new constants. Signed-off-by: Alice Ryhl Reviewed-by: Burak Emir --- rust/kernel/bitmap.rs | 33 +++++++++++++++++++-------------- rust/kernel/id_pool.rs | 39 ++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/rust/kernel/bitmap.rs b/rust/kernel/bitmap.rs index aa8fc7bf06fc99865ae755d8694e4bec3dc8e7f0..0705646c6251a49f213a45f1f01= 3cb9eb2ed81de 100644 --- a/rust/kernel/bitmap.rs +++ b/rust/kernel/bitmap.rs @@ -12,8 +12,6 @@ use crate::pr_err; use core::ptr::NonNull; =20 -const BITS_PER_LONG: usize =3D bindings::BITS_PER_LONG as usize; - /// Represents a C bitmap. Wraps underlying C bitmap API. /// /// # Invariants @@ -149,14 +147,14 @@ macro_rules! bitmap_assert_return { /// /// # Invariants /// -/// * `nbits` is `<=3D i32::MAX` and never changes. -/// * if `nbits <=3D bindings::BITS_PER_LONG`, then `repr` is a `usize`. +/// * `nbits` is `<=3D MAX_LEN`. +/// * if `nbits <=3D MAX_INLINE_LEN`, then `repr` is a `usize`. /// * otherwise, `repr` holds a non-null pointer to an initialized /// array of `unsigned long` that is large enough to hold `nbits` bits. pub struct BitmapVec { /// Representation of bitmap. repr: BitmapRepr, - /// Length of this bitmap. Must be `<=3D i32::MAX`. + /// Length of this bitmap. Must be `<=3D MAX_LEN`. nbits: usize, } =20 @@ -164,7 +162,7 @@ impl core::ops::Deref for BitmapVec { type Target =3D Bitmap; =20 fn deref(&self) -> &Bitmap { - let ptr =3D if self.nbits <=3D BITS_PER_LONG { + let ptr =3D if self.nbits <=3D BitmapVec::MAX_INLINE_LEN { // SAFETY: Bitmap is represented inline. #[allow(unused_unsafe, reason =3D "Safe since Rust 1.92.0")] unsafe { @@ -183,7 +181,7 @@ fn deref(&self) -> &Bitmap { =20 impl core::ops::DerefMut for BitmapVec { fn deref_mut(&mut self) -> &mut Bitmap { - let ptr =3D if self.nbits <=3D BITS_PER_LONG { + let ptr =3D if self.nbits <=3D BitmapVec::MAX_INLINE_LEN { // SAFETY: Bitmap is represented inline. #[allow(unused_unsafe, reason =3D "Safe since Rust 1.92.0")] unsafe { @@ -213,7 +211,7 @@ unsafe impl Sync for BitmapVec {} =20 impl Drop for BitmapVec { fn drop(&mut self) { - if self.nbits <=3D BITS_PER_LONG { + if self.nbits <=3D BitmapVec::MAX_INLINE_LEN { return; } // SAFETY: `self.ptr` was returned by the C `bitmap_zalloc`. @@ -226,23 +224,29 @@ fn drop(&mut self) { } =20 impl BitmapVec { + /// The maximum possible length of a `BitmapVec`. + pub const MAX_LEN: usize =3D i32::MAX as usize; + + /// The maximum length that uses the inline representation. + pub const MAX_INLINE_LEN: usize =3D usize::BITS as usize; + /// Constructs a new [`BitmapVec`]. /// /// Fails with [`AllocError`] when the [`BitmapVec`] could not be allo= cated. This - /// includes the case when `nbits` is greater than `i32::MAX`. + /// includes the case when `nbits` is greater than `MAX_LEN`. #[inline] pub fn new(nbits: usize, flags: Flags) -> Result { - if nbits <=3D BITS_PER_LONG { + if nbits <=3D BitmapVec::MAX_INLINE_LEN { return Ok(BitmapVec { repr: BitmapRepr { bitmap: 0 }, nbits, }); } - if nbits > i32::MAX.try_into().unwrap() { + if nbits > Self::MAX_LEN { return Err(AllocError); } let nbits_u32 =3D u32::try_from(nbits).unwrap(); - // SAFETY: `BITS_PER_LONG < nbits` and `nbits <=3D i32::MAX`. + // SAFETY: `MAX_INLINE_LEN < nbits` and `nbits <=3D MAX_LEN`. let ptr =3D unsafe { bindings::bitmap_zalloc(nbits_u32, flags.as_r= aw()) }; let ptr =3D NonNull::new(ptr).ok_or(AllocError)?; // INVARIANT: `ptr` returned by C `bitmap_zalloc` and `nbits` chec= ked. @@ -495,9 +499,10 @@ mod tests { #[test] fn bitmap_borrow() { let fake_bitmap: [usize; 2] =3D [0, 0]; + let fake_bitmap_len =3D 2 * usize::BITS as usize; // SAFETY: `fake_c_bitmap` is an array of expected length. - let b =3D unsafe { Bitmap::from_raw(fake_bitmap.as_ptr(), 2 * BITS= _PER_LONG) }; - assert_eq!(2 * BITS_PER_LONG, b.len()); + let b =3D unsafe { Bitmap::from_raw(fake_bitmap.as_ptr(), fake_bit= map_len) }; + assert_eq!(fake_bitmap_len, b.len()); assert_eq!(None, b.next_bit(0)); } =20 diff --git a/rust/kernel/id_pool.rs b/rust/kernel/id_pool.rs index a41a3404213ca92d53b14c80101afff6ac8c416e..0b1f720a1f7df8766a8481f3c0b= 332d4cff3b4ad 100644 --- a/rust/kernel/id_pool.rs +++ b/rust/kernel/id_pool.rs @@ -7,8 +7,6 @@ use crate::alloc::{AllocError, Flags}; use crate::bitmap::BitmapVec; =20 -const BITS_PER_LONG: usize =3D bindings::BITS_PER_LONG as usize; - /// Represents a dynamic ID pool backed by a [`BitmapVec`]. /// /// Clients acquire and release IDs from unset bits in a bitmap. @@ -97,13 +95,12 @@ pub fn realloc(&self, flags: Flags) -> Result { impl IdPool { /// Constructs a new [`IdPool`]. /// - /// A capacity below [`BITS_PER_LONG`] is adjusted to - /// [`BITS_PER_LONG`]. + /// A capacity below [`MAX_INLINE_LEN`] is adjusted to [`MAX_INLINE_LE= N`]. /// - /// [`BITS_PER_LONG`]: srctree/include/asm-generic/bitsperlong.h + /// [`MAX_INLINE_LEN`]: BitmapVec::MAX_INLINE_LEN #[inline] pub fn new(num_ids: usize, flags: Flags) -> Result { - let num_ids =3D core::cmp::max(num_ids, BITS_PER_LONG); + let num_ids =3D usize::max(num_ids, BitmapVec::MAX_INLINE_LEN); let map =3D BitmapVec::new(num_ids, flags)?; Ok(Self { map }) } @@ -116,28 +113,34 @@ pub fn capacity(&self) -> usize { =20 /// Returns a [`ReallocRequest`] if the [`IdPool`] can be shrunk, [`No= ne`] otherwise. /// - /// The capacity of an [`IdPool`] cannot be shrunk below [`BITS_PER_LO= NG`]. + /// The capacity of an [`IdPool`] cannot be shrunk below [`MAX_INLINE_= LEN`]. /// - /// [`BITS_PER_LONG`]: srctree/include/asm-generic/bitsperlong.h + /// [`MAX_INLINE_LEN`]: BitmapVec::MAX_INLINE_LEN /// /// # Examples /// /// ``` - /// use kernel::alloc::{AllocError, flags::GFP_KERNEL}; - /// use kernel::id_pool::{ReallocRequest, IdPool}; + /// use kernel::{ + /// alloc::AllocError, + /// bitmap::BitmapVec, + /// id_pool::{ + /// IdPool, + /// ReallocRequest, + /// }, + /// }; /// /// let mut pool =3D IdPool::new(1024, GFP_KERNEL)?; /// let alloc_request =3D pool.shrink_request().ok_or(AllocError)?; /// let resizer =3D alloc_request.realloc(GFP_KERNEL)?; /// pool.shrink(resizer); - /// assert_eq!(pool.capacity(), kernel::bindings::BITS_PER_LONG as usi= ze); + /// assert_eq!(pool.capacity(), BitmapVec::MAX_INLINE_LEN); /// # Ok::<(), AllocError>(()) /// ``` #[inline] pub fn shrink_request(&self) -> Option { let cap =3D self.capacity(); - // Shrinking below [`BITS_PER_LONG`] is never possible. - if cap <=3D BITS_PER_LONG { + // Shrinking below `MAX_INLINE_LEN` is never possible. + if cap <=3D BitmapVec::MAX_INLINE_LEN { return None; } // Determine if the bitmap can shrink based on the position of @@ -146,13 +149,13 @@ pub fn shrink_request(&self) -> Option { // bitmap should shrink to half its current size. let Some(bit) =3D self.map.last_bit() else { return Some(ReallocRequest { - num_ids: BITS_PER_LONG, + num_ids: BitmapVec::MAX_INLINE_LEN, }); }; if bit >=3D (cap / 4) { return None; } - let num_ids =3D usize::max(BITS_PER_LONG, cap / 2); + let num_ids =3D usize::max(BitmapVec::MAX_INLINE_LEN, cap / 2); Some(ReallocRequest { num_ids }) } =20 @@ -177,11 +180,13 @@ pub fn shrink(&mut self, mut resizer: PoolResizer) { =20 /// Returns a [`ReallocRequest`] for growing this [`IdPool`], if possi= ble. /// - /// The capacity of an [`IdPool`] cannot be grown above [`i32::MAX`]. + /// The capacity of an [`IdPool`] cannot be grown above [`MAX_LEN`]. + /// + /// [`MAX_LEN`]: BitmapVec::MAX_LEN #[inline] pub fn grow_request(&self) -> Option { let num_ids =3D self.capacity() * 2; - if num_ids > i32::MAX.try_into().unwrap() { + if num_ids > BitmapVec::MAX_LEN { return None; } Some(ReallocRequest { num_ids }) --=20 2.52.0.460.gd25c4c69ec-goog