Skip to content

Commit 70b9c85

Browse files
DarksonnIngo Molnar
authored andcommitted
rust: sync: condvar: Add wait_interruptible_freezable()
To support waiting for a `CondVar` as a freezable process, add a wait_interruptible_freezable() function. Binder needs this function in the appropriate places to freeze a process where some of its threads are blocked on the Binder driver. [ Boqun: Cleaned up the changelog and documentation. ] Signed-off-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20250307232717.1759087-10-boqun.feng@gmail.com
1 parent c2849af commit 70b9c85

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

rust/kernel/sync/condvar.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use crate::{
1111
init::PinInit,
1212
pin_init,
1313
str::CStr,
14-
task::{MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE},
14+
task::{
15+
MAX_SCHEDULE_TIMEOUT, TASK_FREEZABLE, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE,
16+
},
1517
time::Jiffies,
1618
types::Opaque,
1719
};
@@ -159,6 +161,25 @@ impl CondVar {
159161
crate::current!().signal_pending()
160162
}
161163

164+
/// Releases the lock and waits for a notification in interruptible and freezable mode.
165+
///
166+
/// The process is allowed to be frozen during this sleep. No lock should be held when calling
167+
/// this function, and there is a lockdep assertion for this. Freezing a task that holds a lock
168+
/// can trivially deadlock vs another task that needs that lock to complete before it too can
169+
/// hit freezable.
170+
#[must_use = "wait_interruptible_freezable returns if a signal is pending, so the caller must check the return value"]
171+
pub fn wait_interruptible_freezable<T: ?Sized, B: Backend>(
172+
&self,
173+
guard: &mut Guard<'_, T, B>,
174+
) -> bool {
175+
self.wait_internal(
176+
TASK_INTERRUPTIBLE | TASK_FREEZABLE,
177+
guard,
178+
MAX_SCHEDULE_TIMEOUT,
179+
);
180+
crate::current!().signal_pending()
181+
}
182+
162183
/// Releases the lock and waits for a notification in interruptible mode.
163184
///
164185
/// Atomically releases the given lock (whose ownership is proven by the guard) and puts the

rust/kernel/task.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX;
2323
pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int;
2424
/// Bitmask for tasks that are sleeping in an uninterruptible state.
2525
pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int;
26+
/// Bitmask for tasks that are sleeping in a freezable state.
27+
pub const TASK_FREEZABLE: c_int = bindings::TASK_FREEZABLE as c_int;
2628
/// Convenience constant for waking up tasks regardless of whether they are in interruptible or
2729
/// uninterruptible sleep.
2830
pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint;

0 commit comments

Comments
 (0)