* [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags!
@ 2026-07-16 13:02 Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 1/3] rust_binder: Update defer_work " Jahnavi MN via B4 Relay
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-16 13:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Alice Ryhl, Benno Lossin,
Gary Guo
Cc: linux-kernel, rust-for-linux, Jahnavi MN
In the current Rust Binder driver, internal state variables (thread
looper states, deferred work, and transaction configurations) are
represented as raw integers and manipulated using manual bitwise
operations.
This approach lacks type safety. Because the compiler treats all
integers identically, it is possible to pass a thread looper flag
into a function expecting a transaction flag without triggering
compile-time warnings. These cross-contamination errors compile
cleanly but can cause runtime bugs or undefined behavior.
This patch series resolves this issue by migrating these raw integer
bitmaps (`defer_work`, `looper_flags`, `flags`) to strongly-typed
bitmasks using the `kernel::impl_flags!` macro. Functions now accept
specific, distinct types rather than generic integers, preventing
flags from being mixed up. This transition also replaces manual
bitwise arithmetic with readable, safe methods.
Based on top of:
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
Jahnavi MN (3):
rust_binder: Update defer_work bitmaps to use kernel::impl_flags!
rust_binder: Update looper_flags bitmaps to use kernel::impl_flags!
rust_binder: Update transaction flags to use kernel::impl_flags!
drivers/android/binder/process.rs | 34 +++++++++++------
drivers/android/binder/thread.rs | 69 +++++++++++++++++++++--------------
drivers/android/binder/transaction.rs | 56 +++++++++++++++++++++-------
3 files changed, 105 insertions(+), 54 deletions(-)
---
base-commit: 775553d19b163446c38c5ff24dd0a01065376932
change-id: 20260715-b4-rust_binder_impl_flags-e53b4ebca85d
Best regards,
--
Jahnavi MN <jahnavimn@google.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] rust_binder: Update defer_work bitmaps to use kernel::impl_flags!
2026-07-16 13:02 [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags! Jahnavi MN via B4 Relay
@ 2026-07-16 13:02 ` Jahnavi MN via B4 Relay
2026-07-17 13:22 ` Greg Kroah-Hartman
2026-07-16 13:02 ` [PATCH 2/3] rust_binder: Update looper_flags " Jahnavi MN via B4 Relay
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-16 13:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Alice Ryhl, Benno Lossin,
Gary Guo
Cc: linux-kernel, rust-for-linux, Jahnavi MN
From: Jahnavi MN <jahnavimn@google.com>
- Define `DeferWorks(u8)` and `DeferWork` enum using `bit_u8` offsets.
- Change `ProcessInner.defer_work` type from `u8` to `DeferWorks`.
- Update `Process::release()` and `Process::flush()` to check for empty
states using `DeferWorks::empty()`.
- Update the workqueue runner to inspect flags using `.contains()`.
Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
drivers/android/binder/process.rs | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index 0555c4bd503e..84747d998636 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -16,6 +16,7 @@
use kernel::{
bindings,
+ bits::bit_u8,
cred::Credential,
error::Error,
fs::file::{self, File},
@@ -70,9 +71,18 @@ fn new(address: usize, size: usize) -> Self {
}
}
-// bitflags for defer_work.
-const PROC_DEFER_FLUSH: u8 = 1;
-const PROC_DEFER_RELEASE: u8 = 2;
+kernel::impl_flags!(
+ /// Represents multiple deferred work flags.
+ #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
+ pub struct DeferWorks(u8);
+
+ /// Represents a single deferred work category.
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum DeferWork {
+ Flush = bit_u8(0),
+ Release = bit_u8(1),
+ }
+);
#[derive(Copy, Clone)]
pub(crate) enum IsFrozen {
@@ -121,7 +131,7 @@ pub(crate) struct ProcessInner {
started_thread_count: u32,
/// Bitmap of deferred work to do.
- defer_work: u8,
+ defer_work: DeferWorks,
/// Number of transactions to be transmitted before processes in freeze_wait
/// are woken up.
@@ -151,7 +161,7 @@ fn new() -> Self {
requested_thread_count: 0,
max_threads: 0,
started_thread_count: 0,
- defer_work: 0,
+ defer_work: DeferWorks::default(),
outstanding_txns: 0,
is_frozen: IsFrozen::No,
sync_recv: false,
@@ -489,13 +499,13 @@ fn run(me: Arc<Self>) {
{
let mut inner = me.inner.lock();
defer = inner.defer_work;
- inner.defer_work = 0;
+ inner.defer_work = DeferWorks::default();
}
- if defer & PROC_DEFER_FLUSH != 0 {
+ if defer.contains(DeferWork::Flush) {
me.deferred_flush();
}
- if defer & PROC_DEFER_RELEASE != 0 {
+ if defer.contains(DeferWork::Release) {
me.deferred_release();
}
}
@@ -1649,8 +1659,8 @@ pub(crate) fn release(this: Arc<Process>, _file: &File) {
let should_schedule;
{
let mut inner = this.inner.lock();
- should_schedule = inner.defer_work == 0;
- inner.defer_work |= PROC_DEFER_RELEASE;
+ should_schedule = inner.defer_work == DeferWorks::empty();
+ inner.defer_work |= DeferWork::Release;
binderfs_file = inner.binderfs_file.take();
}
@@ -1667,8 +1677,8 @@ pub(crate) fn flush(this: ArcBorrow<'_, Process>) -> Result {
let should_schedule;
{
let mut inner = this.inner.lock();
- should_schedule = inner.defer_work == 0;
- inner.defer_work |= PROC_DEFER_FLUSH;
+ should_schedule = inner.defer_work == DeferWorks::empty();
+ inner.defer_work |= DeferWork::Flush;
}
if should_schedule {
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] rust_binder: Update looper_flags bitmaps to use kernel::impl_flags!
2026-07-16 13:02 [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags! Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 1/3] rust_binder: Update defer_work " Jahnavi MN via B4 Relay
@ 2026-07-16 13:02 ` Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 3/3] rust_binder: Update transaction flags " Jahnavi MN via B4 Relay
2026-07-17 6:49 ` [PATCH 0/3] rust_binder: Update bitmaps " Alice Ryhl
3 siblings, 0 replies; 6+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-16 13:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Alice Ryhl, Benno Lossin,
Gary Guo
Cc: linux-kernel, rust-for-linux, Jahnavi MN
From: Jahnavi MN <jahnavimn@google.com>
- Define `LooperFlags(u32)` and `LooperFlag` enum with 7 variants.
- Change `InnerThread.looper_flags` type to `LooperFlags`.
- Update looper state transitions and checks to use type-safe methods.
- Convert `looper_flags` to `u32` for hex formatting in `debug_print`.
Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
drivers/android/binder/thread.rs | 63 ++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 19f881948a84..e5bf1eaeeb17 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -9,6 +9,7 @@
use kernel::{
bindings,
+ bits::bit_u32,
fs::{File, LocalFile},
list::{AtomicTracker, List, ListArc, ListLinks, TryNewListArc},
prelude::*,
@@ -243,7 +244,7 @@ fn is_ok(&self) -> bool {
struct InnerThread {
/// Determines the looper state of the thread. It is a bit-wise combination of the constants
/// prefixed with `LOOPER_`.
- looper_flags: u32,
+ looper_flags: LooperFlags,
/// Determines whether the looper should return.
looper_need_return: bool,
@@ -270,13 +271,23 @@ struct InnerThread {
extended_error: ExtendedError,
}
-const LOOPER_REGISTERED: u32 = 0x01;
-const LOOPER_ENTERED: u32 = 0x02;
-const LOOPER_EXITED: u32 = 0x04;
-const LOOPER_INVALID: u32 = 0x08;
-const LOOPER_WAITING: u32 = 0x10;
-const LOOPER_WAITING_PROC: u32 = 0x20;
-const LOOPER_POLL: u32 = 0x40;
+kernel::impl_flags!(
+ /// Represents multiple looper flags.
+ #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
+ pub struct LooperFlags(u32);
+
+ /// Represents a single looper flag.
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum LooperFlag {
+ Registered = bit_u32(0),
+ Entered = bit_u32(1),
+ Exited = bit_u32(2),
+ Invalid = bit_u32(3),
+ Waiting = bit_u32(4),
+ WaitingProc = bit_u32(5),
+ Poll = bit_u32(6),
+ }
+);
impl InnerThread {
fn new() -> Result<Self> {
@@ -286,7 +297,7 @@ fn next_err_id() -> u32 {
}
Ok(Self {
- looper_flags: 0,
+ looper_flags: LooperFlags::default(),
looper_need_return: false,
is_dead: false,
process_work_list: false,
@@ -373,26 +384,27 @@ fn pop_transaction_replied(&mut self, transaction: &DArc<Transaction>) -> bool {
}
fn looper_enter(&mut self) {
- self.looper_flags |= LOOPER_ENTERED;
- if self.looper_flags & LOOPER_REGISTERED != 0 {
- self.looper_flags |= LOOPER_INVALID;
+ self.looper_flags |= LooperFlag::Entered;
+ if self.looper_flags.contains(LooperFlag::Registered) {
+ self.looper_flags |= LooperFlag::Invalid;
}
}
fn looper_register(&mut self, valid: bool) {
- self.looper_flags |= LOOPER_REGISTERED;
- if !valid || self.looper_flags & LOOPER_ENTERED != 0 {
- self.looper_flags |= LOOPER_INVALID;
+ self.looper_flags |= LooperFlag::Registered;
+ if !valid || self.looper_flags.contains(LooperFlag::Entered) {
+ self.looper_flags |= LooperFlag::Invalid;
}
}
fn looper_exit(&mut self) {
- self.looper_flags |= LOOPER_EXITED;
+ self.looper_flags |= LooperFlag::Exited;
}
/// Determines whether the thread is part of a pool, i.e., if it is a looper.
fn is_looper(&self) -> bool {
- self.looper_flags & (LOOPER_ENTERED | LOOPER_REGISTERED) != 0
+ self.looper_flags
+ .contains_any(LooperFlag::Entered | LooperFlag::Registered)
}
/// Determines whether the thread should attempt to fetch work items from the process queue.
@@ -404,7 +416,7 @@ fn should_use_process_work_queue(&self) -> bool {
}
fn poll(&mut self) -> u32 {
- self.looper_flags |= LOOPER_POLL;
+ self.looper_flags |= LooperFlag::Poll;
if self.process_work_list || self.looper_need_return {
bindings::POLLIN
} else {
@@ -470,7 +482,7 @@ pub(crate) fn debug_print(self: &Arc<Self>, m: &SeqFile, print_all: bool) -> Res
m,
" thread {}: l {:02x} need_return {}\n",
self.id,
- inner.looper_flags,
+ u32::from(inner.looper_flags),
inner.looper_need_return,
);
}
@@ -543,9 +555,9 @@ fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn Deliv
return Ok(Some(work));
}
- inner.looper_flags |= LOOPER_WAITING;
+ inner.looper_flags |= LooperFlag::Waiting;
let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner);
- inner.looper_flags &= !LOOPER_WAITING;
+ inner.looper_flags &= !LooperFlag::Waiting;
if signal_pending {
return Err(EINTR);
@@ -597,9 +609,9 @@ fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRe
return Ok(Some(work));
}
- inner.looper_flags |= LOOPER_WAITING | LOOPER_WAITING_PROC;
+ inner.looper_flags |= LooperFlag::Waiting | LooperFlag::WaitingProc;
let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner);
- inner.looper_flags &= !(LOOPER_WAITING | LOOPER_WAITING_PROC);
+ inner.looper_flags &= !(LooperFlag::Waiting | LooperFlag::WaitingProc);
if signal_pending || inner.looper_need_return {
// We need to return now. We need to pull the thread off the list of ready threads
@@ -1589,7 +1601,7 @@ pub(crate) fn poll(&self, file: &File, table: PollTable<'_>) -> (bool, u32) {
/// Make the call to `get_work` or `get_work_local` return immediately, if any.
pub(crate) fn exit_looper(&self) {
let mut inner = self.inner.lock();
- let should_notify = inner.looper_flags & LOOPER_WAITING != 0;
+ let should_notify = inner.looper_flags.contains(LooperFlag::Waiting);
if should_notify {
inner.looper_need_return = true;
}
@@ -1603,7 +1615,8 @@ pub(crate) fn exit_looper(&self) {
pub(crate) fn notify_if_poll_ready(&self, sync: bool) {
// Determine if we need to notify. This requires the lock.
let inner = self.inner.lock();
- let notify = inner.looper_flags & LOOPER_POLL != 0 && inner.should_use_process_work_queue();
+ let notify =
+ inner.looper_flags.contains(LooperFlag::Poll) && inner.should_use_process_work_queue();
drop(inner);
// Now that the lock is no longer held, notify the waiters if we have to.
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] rust_binder: Update transaction flags to use kernel::impl_flags!
2026-07-16 13:02 [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags! Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 1/3] rust_binder: Update defer_work " Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 2/3] rust_binder: Update looper_flags " Jahnavi MN via B4 Relay
@ 2026-07-16 13:02 ` Jahnavi MN via B4 Relay
2026-07-17 6:49 ` [PATCH 0/3] rust_binder: Update bitmaps " Alice Ryhl
3 siblings, 0 replies; 6+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-16 13:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Alice Ryhl, Benno Lossin,
Gary Guo
Cc: linux-kernel, rust-for-linux, Jahnavi MN
From: Jahnavi MN <jahnavimn@google.com>
- Define `TransactionFlags(u32)` and `TransactionFlag` with 4 variants.
- Change flags field type to `TransactionFlags` in structs.
- Add `is_oneway` helper on `TransactionFlags` to simplify checks.
- Update `can_replace` logic to use type-safe combined flag checks.
- Convert `flags` to `u32` for FFI boundaries and logging.
Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
drivers/android/binder/thread.rs | 6 ++--
drivers/android/binder/transaction.rs | 56 ++++++++++++++++++++++++++---------
2 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index e5bf1eaeeb17..1d10c6a95ff5 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -31,7 +31,7 @@
process::{GetWorkOrRegister, Process},
ptr_align,
stats::GLOBAL_STATS,
- transaction::{Transaction, TransactionInfo},
+ transaction::{Transaction, TransactionFlag, TransactionFlags, TransactionInfo},
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead,
};
@@ -1244,7 +1244,7 @@ fn read_transaction_info(
info.from_pid = self.process.task.pid();
info.from_tid = self.id;
info.code = td.transaction_data.code;
- info.flags = td.transaction_data.flags;
+ info.flags = TransactionFlags::from_bits(td.transaction_data.flags);
info.data_ptr = UserPtr::from_addr(trd_data_ptr.buffer as usize);
info.data_size = td.transaction_data.data_size as usize;
info.offsets_ptr = UserPtr::from_addr(trd_data_ptr.offsets as usize);
@@ -1350,7 +1350,7 @@ fn reply_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
let out = (|| -> BinderResult<_> {
let completion = DTRWrap::arc_try_new(DeliverCode::new(BR_TRANSACTION_COMPLETE))?;
let process = orig.from.process.clone();
- let allow_fds = orig.flags & TF_ACCEPT_FDS != 0;
+ let allow_fds = orig.flags.contains(TransactionFlag::AcceptFds);
let reply = Transaction::new_reply(self, process, info, allow_fds)?;
self.inner.lock().push_work(completion);
orig.from.deliver_reply(Ok(reply), &orig, None);
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index afef5b46eac2..4e2ef99e512f 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -25,6 +25,33 @@
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead,
};
+kernel::impl_flags!(
+ /// Represents multiple transaction flags.
+ #[derive(Debug, Clone, Default, Copy, PartialEq, Eq, Zeroable)]
+ pub struct TransactionFlags(u32);
+
+ /// Represents a single transaction flag.
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum TransactionFlag {
+ OneWay = TF_ONE_WAY,
+ AcceptFds = TF_ACCEPT_FDS,
+ ClearBuf = TF_CLEAR_BUF,
+ UpdateTxn = TF_UPDATE_TXN,
+ }
+);
+
+impl TransactionFlags {
+ /// Creates a `TransactionFlags` from a raw `u32` value.
+ pub(crate) fn from_bits(bits: u32) -> Self {
+ Self(bits)
+ }
+
+ /// Checks if the Oneway flag is set.
+ pub(crate) fn is_oneway(self) -> bool {
+ self.contains(TransactionFlag::OneWay)
+ }
+}
+
#[derive(Zeroable)]
pub(crate) struct TransactionInfo {
pub(crate) from_pid: Pid,
@@ -32,7 +59,7 @@ pub(crate) struct TransactionInfo {
pub(crate) to_pid: Pid,
pub(crate) to_tid: Pid,
pub(crate) code: u32,
- pub(crate) flags: u32,
+ pub(crate) flags: TransactionFlags,
pub(crate) data_ptr: UserPtr,
pub(crate) data_size: usize,
pub(crate) offsets_ptr: UserPtr,
@@ -49,7 +76,7 @@ pub(crate) struct TransactionInfo {
impl TransactionInfo {
#[inline]
pub(crate) fn is_oneway(&self) -> bool {
- self.flags & TF_ONE_WAY != 0
+ self.flags.is_oneway()
}
}
@@ -75,7 +102,7 @@ pub(crate) struct Transaction {
allocation: SpinLock<Option<Allocation>>,
is_outstanding: Atomic<bool>,
code: u32,
- pub(crate) flags: u32,
+ pub(crate) flags: TransactionFlags,
data_size: usize,
offsets_size: usize,
data_address: usize,
@@ -121,7 +148,7 @@ pub(crate) fn new(
}
alloc.set_info_oneway_node(node_ref.node.clone());
}
- if info.flags & TF_CLEAR_BUF != 0 {
+ if info.flags.contains(TransactionFlag::ClearBuf) {
alloc.set_info_clear_on_drop();
}
let target_node = node_ref.node.clone();
@@ -161,7 +188,7 @@ pub(crate) fn new_reply(
return Err(err);
}
};
- if info.flags & TF_CLEAR_BUF != 0 {
+ if info.flags.contains(TransactionFlag::ClearBuf) {
alloc.set_info_clear_on_drop();
}
Ok(DTRWrap::arc_pin_init(pin_init!(Transaction {
@@ -194,7 +221,7 @@ pub(crate) fn debug_print_inner(&self, m: &SeqFile, prefix: &str) {
self.from.id,
self.to.task.pid(),
self.code,
- self.flags,
+ u32::from(self.flags),
self.start_time.elapsed().as_millis(),
);
if let Some(target_node) = &self.target_node {
@@ -273,7 +300,7 @@ pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderRes
let _t_outdated;
let _oneway_node;
- let oneway = self.flags & TF_ONE_WAY != 0;
+ let oneway = self.flags.is_oneway();
let process = self.to.clone();
let mut process_inner = process.inner.lock();
@@ -284,7 +311,7 @@ pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderRes
crate::trace::trace_transaction(false, &self, None);
if process_inner.is_frozen.is_frozen() {
process_inner.async_recv = true;
- if self.flags & TF_UPDATE_TXN != 0 {
+ if self.flags.contains(TransactionFlag::UpdateTxn) {
if let Some(t_outdated) =
target_node.take_outdated_transaction(&self, &mut process_inner)
{
@@ -355,7 +382,8 @@ pub(crate) fn can_replace(&self, old: &Transaction) -> bool {
return false;
}
- if self.flags & old.flags & (TF_ONE_WAY | TF_UPDATE_TXN) != (TF_ONE_WAY | TF_UPDATE_TXN) {
+ let required = TransactionFlag::OneWay | TransactionFlag::UpdateTxn;
+ if !(self.flags.contains_all(required) && old.flags.contains_all(required)) {
return false;
}
@@ -392,7 +420,7 @@ fn do_work(
writer: &mut BinderReturnWriter<'_>,
) -> Result<bool> {
let send_failed_reply = ScopeGuard::new(|| {
- if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
+ if self.target_node.is_some() && !self.flags.is_oneway() {
let reply = Err(BR_FAILED_REPLY);
self.from.deliver_reply(reply, &self, None);
}
@@ -415,7 +443,7 @@ fn do_work(
tr.cookie = cookie as uapi::binder_uintptr_t;
};
tr.code = self.code;
- tr.flags = self.flags;
+ tr.flags = u32::from(self.flags);
tr.data_size = self.data_size as uapi::binder_size_t;
tr.data.ptr.buffer = self.data_address as uapi::binder_uintptr_t;
tr.offsets_size = self.offsets_size as uapi::binder_size_t;
@@ -425,7 +453,7 @@ fn do_work(
}
tr.sender_euid = self.sender_euid.into_uid_in_current_ns();
tr.sender_pid = 0;
- if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
+ if self.target_node.is_some() && !self.flags.is_oneway() {
// Not a reply and not one-way.
tr.sender_pid = self.from.process.pid_in_current_ns();
}
@@ -477,7 +505,7 @@ fn cancel(self: DArc<Self>) {
drop(allocation);
// If this is not a reply or oneway transaction, then send a dead reply.
- if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
+ if self.target_node.is_some() && !self.flags.is_oneway() {
let reply = Err(BR_DEAD_REPLY);
self.from.deliver_reply(reply, &self, None);
}
@@ -486,7 +514,7 @@ fn cancel(self: DArc<Self>) {
}
fn should_sync_wakeup(&self) -> bool {
- self.flags & TF_ONE_WAY == 0
+ !self.flags.is_oneway()
}
fn debug_print(&self, m: &SeqFile, _prefix: &str, tprefix: &str) -> Result<()> {
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags!
2026-07-16 13:02 [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags! Jahnavi MN via B4 Relay
` (2 preceding siblings ...)
2026-07-16 13:02 ` [PATCH 3/3] rust_binder: Update transaction flags " Jahnavi MN via B4 Relay
@ 2026-07-17 6:49 ` Alice Ryhl
3 siblings, 0 replies; 6+ messages in thread
From: Alice Ryhl @ 2026-07-17 6:49 UTC (permalink / raw)
To: jahnavimn
Cc: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Benno Lossin, Gary Guo,
linux-kernel, rust-for-linux
On Thu, Jul 16, 2026 at 01:02:33PM +0000, Jahnavi MN via B4 Relay wrote:
> In the current Rust Binder driver, internal state variables (thread
> looper states, deferred work, and transaction configurations) are
> represented as raw integers and manipulated using manual bitwise
> operations.
>
> This approach lacks type safety. Because the compiler treats all
> integers identically, it is possible to pass a thread looper flag
> into a function expecting a transaction flag without triggering
> compile-time warnings. These cross-contamination errors compile
> cleanly but can cause runtime bugs or undefined behavior.
>
> This patch series resolves this issue by migrating these raw integer
> bitmaps (`defer_work`, `looper_flags`, `flags`) to strongly-typed
> bitmasks using the `kernel::impl_flags!` macro. Functions now accept
> specific, distinct types rather than generic integers, preventing
> flags from being mixed up. This transition also replaces manual
> bitwise arithmetic with readable, safe methods.
>
> Based on top of:
> https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
>
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
It would be nice if our impl_flags! macro could allow us to omit the
right-hand-side that's saying `= bit_u8(i)` here:
/// Represents a single deferred work category.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeferWork {
Flush = bit_u8(0),
Release = bit_u8(1),
}
After all, if we don't care what values the bits take, the macro could
just assign them for us.
Alice
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] rust_binder: Update defer_work bitmaps to use kernel::impl_flags!
2026-07-16 13:02 ` [PATCH 1/3] rust_binder: Update defer_work " Jahnavi MN via B4 Relay
@ 2026-07-17 13:22 ` Greg Kroah-Hartman
0 siblings, 0 replies; 6+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-17 13:22 UTC (permalink / raw)
To: jahnavimn
Cc: Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Alice Ryhl, Benno Lossin, Gary Guo, linux-kernel,
rust-for-linux
On Thu, Jul 16, 2026 at 01:02:34PM +0000, Jahnavi MN via B4 Relay wrote:
> From: Jahnavi MN <jahnavimn@google.com>
>
> - Define `DeferWorks(u8)` and `DeferWork` enum using `bit_u8` offsets.
> - Change `ProcessInner.defer_work` type from `u8` to `DeferWorks`.
> - Update `Process::release()` and `Process::flush()` to check for empty
> states using `DeferWorks::empty()`.
> - Update the workqueue runner to inspect flags using `.contains()`.
>
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>
> ---
> drivers/android/binder/process.rs | 34 ++++++++++++++++++++++------------
> 1 file changed, 22 insertions(+), 12 deletions(-)
This is the only patch in the series that applied. Can you rebase and
resend the other 2?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-17 13:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 13:02 [PATCH 0/3] rust_binder: Update bitmaps to use kernel::impl_flags! Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 1/3] rust_binder: Update defer_work " Jahnavi MN via B4 Relay
2026-07-17 13:22 ` Greg Kroah-Hartman
2026-07-16 13:02 ` [PATCH 2/3] rust_binder: Update looper_flags " Jahnavi MN via B4 Relay
2026-07-16 13:02 ` [PATCH 3/3] rust_binder: Update transaction flags " Jahnavi MN via B4 Relay
2026-07-17 6:49 ` [PATCH 0/3] rust_binder: Update bitmaps " Alice Ryhl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox