When Rust Binder assigns a new ID, it performs various fallible
operations before it "commits" to actually using the new ID. To support
this pattern, change acquire_next_id() so that it does not immediately
call set_bit(), but instead returns an object that may be used to call
set_bit() later.
The UnusedId type holds a exclusive reference to the IdPool, so it's
guaranteed that nobody else can call find_unused_id() while the UnusedId
object is live.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
rust/kernel/id_pool.rs | 44 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/rust/kernel/id_pool.rs b/rust/kernel/id_pool.rs
index 126e57f34c3407cb1dab3169417f01917e172dee..053ca417e8513fc33afc84c194d7899eafac8fec 100644
--- a/rust/kernel/id_pool.rs
+++ b/rust/kernel/id_pool.rs
@@ -199,18 +199,16 @@ pub fn grow(&mut self, mut resizer: PoolResizer) {
self.map = resizer.new;
}
- /// Acquires a new ID by finding and setting the next zero bit in the
- /// bitmap.
+ /// Finds an unused ID in the bitmap.
///
/// Upon success, returns its index. Otherwise, returns [`None`]
/// to indicate that a [`Self::grow_request`] is needed.
#[inline]
- pub fn acquire_next_id(&mut self, offset: usize) -> Option<usize> {
- let next_zero_bit = self.map.next_zero_bit(offset);
- if let Some(nr) = next_zero_bit {
- self.map.set_bit(nr);
- }
- next_zero_bit
+ pub fn find_unused_id(&mut self, offset: usize) -> Option<UnusedId<'_>> {
+ Some(UnusedId {
+ id: self.map.next_zero_bit(offset)?,
+ pool: self,
+ })
}
/// Releases an ID.
@@ -220,6 +218,36 @@ pub fn release_id(&mut self, id: usize) {
}
}
+/// Represents an unused id in an [`IdPool`].
+pub struct UnusedId<'pool> {
+ id: usize,
+ pool: &'pool mut IdPool,
+}
+
+impl<'pool> UnusedId<'pool> {
+ /// Get the unused id as an usize.
+ ///
+ /// Be aware that the id has not yet been acquired in the pool. The
+ /// [`acquire`] method must be called to prevent others from taking the id.
+ pub fn as_usize(&self) -> usize {
+ self.id
+ }
+
+ /// Get the unused id as an u32.
+ ///
+ /// Be aware that the id has not yet been acquired in the pool. The
+ /// [`acquire`] method must be called to prevent others from taking the id.
+ pub fn as_u32(&self) -> u32 {
+ // CAST: The maximum possible value in an IdPool is i32::MAX.
+ self.id as u32
+ }
+
+ /// Acquire the unused id.
+ pub fn acquire(self) {
+ self.pool.map.set_bit(self.id);
+ }
+}
+
impl Default for IdPool {
#[inline]
fn default() -> Self {
--
2.51.0.869.ge66316f041-goog
Hi Alice,
kernel test robot noticed the following build errors:
[auto build test ERROR on 211ddde0823f1442e4ad052a2f30f050145ccada]
url: https://github.com/intel-lab-lkp/linux/commits/Alice-Ryhl/rust-bitmap-add-MAX_LEN-and-NO_ALLOC_MAX_LEN-constants/20251021-213620
base: 211ddde0823f1442e4ad052a2f30f050145ccada
patch link: https://lore.kernel.org/r/20251021-binder-bitmap-v2-4-e652d172c62b%40google.com
patch subject: [PATCH v2 4/5] rust: id_pool: do not immediately acquire new ids
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20251023/202510230839.DJZaY5US-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251023/202510230839.DJZaY5US-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510230839.DJZaY5US-lkp@intel.com/
All errors (new ones prefixed by >>):
>> error[E0599]: no method named `acquire_next_id` found for struct `Guard<'_, IdPool, SpinLockBackend>` in the current scope
--> rust/doctests_kernel_generated.rs:6515:20
|
6515 | match pool.acquire_next_id(0) {
| ^^^^^^^^^^^^^^^ method not found in `Guard<'_, IdPool, SpinLockBackend>`
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Tue, Oct 21, 2025 at 3:33 PM Alice Ryhl <aliceryhl@google.com> wrote: > > When Rust Binder assigns a new ID, it performs various fallible > operations before it "commits" to actually using the new ID. To support > this pattern, change acquire_next_id() so that it does not immediately > call set_bit(), but instead returns an object that may be used to call > set_bit() later. > > The UnusedId type holds a exclusive reference to the IdPool, so it's > guaranteed that nobody else can call find_unused_id() while the UnusedId > object is live. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Burak Emir <bqe@google.com>
© 2016 - 2026 Red Hat, Inc.