* [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* 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
* [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