[PATCH v8 11/12] rust: id_pool: do not round capacity up to BitmapVec::MAX_INLINE_LEN
From: Eliot Courtney
Date: Thu Aug 27 2026 - 03:32:59 EST
Current code in IdPool::with_capacity rounds the capacity up to
BitmapVec::MAX_INLINE_LEN, but BitmapVec::new works fine with values
smaller than this and still uses an inline representation. Remove this
behaviour.
This allows specifying a real capacity of 0, which was not previously
possible. This breaks `grow_request` in this case, so change it to grow
to at least `BitmapVec::MAX_INLINE_LEN`, mirroring the capacity floor in
`shrink_request`.
Signed-off-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
---
rust/kernel/id_pool.rs | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/rust/kernel/id_pool.rs b/rust/kernel/id_pool.rs
index 06a4c71c4c6c..4f329249df9d 100644
--- a/rust/kernel/id_pool.rs
+++ b/rust/kernel/id_pool.rs
@@ -112,13 +112,8 @@ pub fn new() -> Self {
}
/// Constructs a new [`IdPool`] with space for a specific number of bits.
- ///
- /// A capacity below [`MAX_INLINE_LEN`] is adjusted to [`MAX_INLINE_LEN`].
- ///
- /// [`MAX_INLINE_LEN`]: BitmapVec::MAX_INLINE_LEN
#[inline]
pub fn with_capacity(num_ids: usize, flags: Flags) -> Result<Self, AllocError> {
- let num_ids = usize::max(num_ids, BitmapVec::MAX_INLINE_LEN);
let map = BitmapVec::new(num_ids, flags)?;
Ok(Self { map })
}
@@ -152,6 +147,13 @@ pub fn capacity(&self) -> usize {
/// let resizer = alloc_request.realloc(GFP_KERNEL)?;
/// pool.shrink(resizer);
/// assert_eq!(pool.capacity(), BitmapVec::MAX_INLINE_LEN);
+ ///
+ /// // A pool at the `MAX_INLINE_LEN` floor cannot shrink further.
+ /// assert!(pool.shrink_request().is_none());
+ ///
+ /// // Neither can a pool with a capacity below `MAX_INLINE_LEN`.
+ /// let small = IdPool::with_capacity(8, GFP_KERNEL)?;
+ /// assert!(small.shrink_request().is_none());
/// # Ok::<(), AllocError>(())
/// ```
#[inline]
@@ -198,12 +200,36 @@ pub fn shrink(&mut self, mut resizer: PoolResizer) {
/// Returns a [`ReallocRequest`] for growing this [`IdPool`], if possible.
///
+ /// Grows to at least [`MAX_INLINE_LEN`].
/// The capacity of an [`IdPool`] cannot be grown above [`MAX_LEN`].
///
+ /// [`MAX_INLINE_LEN`]: BitmapVec::MAX_INLINE_LEN
/// [`MAX_LEN`]: BitmapVec::MAX_LEN
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::{
+ /// alloc::AllocError,
+ /// bitmap::BitmapVec,
+ /// id_pool::IdPool, //
+ /// };
+ ///
+ /// // Grow goes to at least BitmapVec::MAX_INLINE_LEN.
+ /// let mut pool = IdPool::with_capacity(0, GFP_KERNEL)?;
+ /// let resizer = pool.grow_request().ok_or(AllocError)?.realloc(GFP_KERNEL)?;
+ /// pool.grow(resizer);
+ /// assert_eq!(pool.capacity(), BitmapVec::MAX_INLINE_LEN);
+ ///
+ /// // Grow doubles if at least BitmapVec::MAX_INLINE_LEN.
+ /// let resizer = pool.grow_request().ok_or(AllocError)?.realloc(GFP_KERNEL)?;
+ /// pool.grow(resizer);
+ /// assert_eq!(pool.capacity(), 2 * BitmapVec::MAX_INLINE_LEN);
+ /// # Ok::<(), AllocError>(())
+ /// ```
#[inline]
pub fn grow_request(&self) -> Option<ReallocRequest> {
- let num_ids = self.capacity() * 2;
+ let num_ids = usize::max(BitmapVec::MAX_INLINE_LEN, self.capacity() * 2);
if num_ids > BitmapVec::MAX_LEN {
return None;
}
--
2.55.0