[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251021-binder-bitmap-v2-4-e652d172c62b@google.com>
Date: Tue, 21 Oct 2025 13:32:46 +0000
From: Alice Ryhl <aliceryhl@...gle.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>, Yury Norov <yury.norov@...il.com>
Cc: "Arve Hjønnevåg" <arve@...roid.com>, Todd Kjos <tkjos@...roid.com>,
Martijn Coenen <maco@...roid.com>, Joel Fernandes <joelagnelf@...dia.com>,
Christian Brauner <brauner@...nel.org>, Carlos Llamas <cmllamas@...gle.com>,
Suren Baghdasaryan <surenb@...gle.com>, Burak Emir <bqe@...gle.com>, Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
"Björn Roy Baron" <bjorn3_gh@...tonmail.com>, Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>, Trevor Gross <tmgross@...ch.edu>,
Danilo Krummrich <dakr@...nel.org>, rust-for-linux@...r.kernel.org,
linux-kernel@...r.kernel.org, Alice Ryhl <aliceryhl@...gle.com>
Subject: [PATCH v2 4/5] rust: id_pool: do not immediately acquire new ids
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@...gle.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
Powered by blists - more mailing lists