ANDROID: rust: add Task methods for priority inheritance

This CL adds methods for manipulating the priority of a task that I have
not upstreamed due to Binder priority inheritance being OOT.

Bug: 388786466
Change-Id: Ife8cd03f12b5dde674e5da4576341555ea6b0179
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2025-01-29 14:37:54 +00:00
parent 293cc8c860
commit c0d8982f50
2 changed files with 70 additions and 0 deletions
+6
View File
@@ -55,3 +55,9 @@ pid_t rust_helper_task_tgid_nr_ns(struct task_struct *tsk,
{
return task_tgid_nr_ns(tsk, ns);
}
unsigned long rust_helper_task_rlimit(const struct task_struct *task,
unsigned int limit)
{
return task_rlimit(task, limit);
}
+64
View File
@@ -251,6 +251,70 @@ impl Task {
// running.
unsafe { bindings::wake_up_process(self.as_ptr()) };
}
/// Check if the task has the given capability without logging to the audit log.
pub fn has_capability_noaudit(&self, capability: i32) -> bool {
// SAFETY: By the type invariant, we know that `self.0.get()` is valid.
unsafe { bindings::has_capability_noaudit(self.0.get(), capability) }
}
/// Returns the current scheduling policy.
pub fn policy(&self) -> u32 {
// SAFETY: The file is valid because the shared reference guarantees a nonzero refcount.
//
// This uses a volatile read because C code may be modifying this field in parallel using
// non-atomic unsynchronized writes. This corresponds to how the C macro READ_ONCE is
// implemented.
unsafe { core::ptr::addr_of!((*self.0.get()).policy).read_volatile() }
}
/// Returns the current normal priority.
pub fn normal_prio(&self) -> i32 {
// SAFETY: The file is valid because the shared reference guarantees a nonzero refcount.
//
// This uses a volatile read because C code may be modifying this field in parallel using
// non-atomic unsynchronized writes. This corresponds to how the C macro READ_ONCE is
// implemented.
unsafe { core::ptr::addr_of!((*self.0.get()).normal_prio).read_volatile() }
}
/// Get the rlimit value for RTPRIO.
pub fn rlimit_rtprio(&self) -> i32 {
// SAFETY: By the type invariant, we know that `self.0.get()` is valid, and RLIMIT_RTPRIO
// is a valid limit type.
unsafe { bindings::task_rlimit(self.0.get(), bindings::RLIMIT_RTPRIO) as i32 }
}
/// Get the rlimit value for NICE, converted to a nice value.
pub fn rlimit_nice(&self) -> i32 {
// SAFETY: By the type invariant, we know that `self.0.get()` is valid, and RLIMIT_NICE
// is a valid limit type.
let prio = unsafe { bindings::task_rlimit(self.0.get(), bindings::RLIMIT_NICE) as i32 };
// Convert rlimit style value [1,40] to nice value [-20, 19].
bindings::MAX_NICE as i32 - prio + 1
}
/// Set the scheduling properties for this task without checking whether the task is allowed to
/// set them.
pub fn sched_setscheduler_nocheck(
&self,
policy: i32,
sched_priority: i32,
reset_on_fork: bool,
) {
let params = bindings::sched_param { sched_priority };
let mut policy = policy;
if reset_on_fork {
policy |= bindings::SCHED_RESET_ON_FORK as i32;
}
unsafe { bindings::sched_setscheduler_nocheck(self.0.get(), policy, &params) };
}
/// Set the nice value of this task.
pub fn set_user_nice(&self, nice: i32) {
unsafe { bindings::set_user_nice(self.0.get(), nice as _) };
}
}
impl CurrentTask {