kernel: add SchedPolicy/Name/Priority proc scheme handles

Wire up three new ContextHandle variants and their /proc/<pid>/{name,
sched-policy, priority} paths so that userspace (libredox, relibc's
pthread_setname_np / pthread_setschedparam / setpriority) can read
and write these per-context fields.

Changes:

  ContextHandle enum (proc.rs:103-153):
    - Add SchedPolicy (write: [policy, rt_priority] u8,u8;
                       read:  [policy, rt_priority] u8,u8)
    - Add Name       (write: up-to-32-byte UTF-8 string, NUL-trimmed;
                       read:  the stored ArrayString bytes)
    - Add Priority   (write: i32 nice value, range-checked to -20..=19;
                       read:  i32 nice value computed from context.prio)

  openat_context paths (proc.rs:251-254):
    - 'sched-policy' -> ContextHandle::SchedPolicy
    - 'name'         -> ContextHandle::Name
    - 'priority'     -> ContextHandle::Priority

  Attr write handler (proc.rs:1286):
    - Switched from 'guard.prio = (info.prio as usize).min(39)'
      to 'guard.set_sched_other_prio(info.prio as usize)' so that
      both prio AND sched_static_prio are kept in sync. Previously
      sched_static_prio (used by the DWRR weight table) was never
      updated from userspace, so the kernel's fair-scheduling
      weight stayed at the initial value forever.

Combined with the prior commit 'add Context::set_sched_policy and
set_sched_other_prio', this completes the userspace API for
threading control:
  - pthread_setname_np        -> /proc/<tid>/name
  - sched_setscheduler        -> /proc/<tid>/sched-policy
  - setpriority / nice        -> /proc/<tid>/priority
  - pthread_setschedparam     -> /proc/<tid>/sched-policy + /proc/<tid>/priority

cargo check: now exits 0 with 0 errors. 37 warnings remain (all
pre-existing, none blocking).

Upstream check: verified via the bg_27f3578a audit that upstream
Redox kernel has NONE of these features; the local fork is the
sole implementation.
This commit is contained in:
2026-07-02 07:00:07 +03:00
parent e8ec916158
commit 4789d546e2
+64 -2
View File
@@ -1,7 +1,7 @@
use crate::{
context::{
self,
context::{HardBlockedReason, LockedFdTbl, SignalState},
context::{HardBlockedReason, LockedFdTbl, SchedPolicy, SignalState},
file::InternalFlags,
memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan},
Context, ContextLock, Status,
@@ -146,6 +146,9 @@ enum ContextHandle {
// directory.
OpenViaDup,
SchedAffinity,
SchedPolicy,
Name,
Priority,
MmapMinAddr(Arc<AddrSpaceWrapper>),
}
@@ -250,6 +253,9 @@ impl ProcScheme {
false,
),
"sched-affinity" => (ContextHandle::SchedAffinity, true),
"sched-policy" => (ContextHandle::SchedPolicy, true),
"name" => (ContextHandle::Name, true),
"priority" => (ContextHandle::Priority, true),
"status" => (ContextHandle::Status { privileged: false }, false),
_ if path.starts_with("auth-") => {
let nonprefix = &path["auth-".len()..];
@@ -1172,6 +1178,45 @@ impl ContextHandle {
Ok(size_of_val(&mask))
}
Self::SchedPolicy => {
if buf.len() != 2 {
return Err(Error::new(EINVAL));
}
let [policy, rt_priority] = unsafe { buf.read_exact::<[u8; 2]>()? };
let sched_policy = SchedPolicy::try_from_raw(policy).ok_or(Error::new(EINVAL))?;
context
.write(token.token())
.set_sched_policy(sched_policy, rt_priority);
Ok(2)
}
Self::Name => {
let bytes = unsafe { buf.read_exact::<[u8; 32]>()? };
let len = bytes
.iter()
.position(|&b| b == 0)
.unwrap_or(bytes.len());
let name = core::str::from_utf8(&bytes[..len]).map_err(|_| Error::new(EINVAL))?;
context.write(token.token()).name.clear();
context.write(token.token()).name.push_str(name);
Ok(bytes.len())
}
Self::Priority => {
if buf.len() != size_of::<i32>() {
return Err(Error::new(EINVAL));
}
let nice = unsafe { buf.read_exact::<i32>()? };
if !(-20..=19).contains(&nice) {
return Err(Error::new(EINVAL));
}
let kernel_prio = (20 - nice) as usize;
context
.write(token.token())
.set_sched_other_prio(kernel_prio);
Ok(size_of::<i32>())
}
ContextHandle::Status { privileged } => {
let mut args = buf.usizes();
@@ -1275,7 +1320,7 @@ impl ContextHandle {
guard.pid = info.pid as usize;
guard.euid = info.euid;
guard.egid = info.egid;
guard.prio = (info.prio as usize).min(39);
guard.set_sched_other_prio(info.prio as usize);
Ok(size_of::<ProcSchemeAttrs>())
}
Self::Groups => {
@@ -1467,6 +1512,23 @@ impl ContextHandle {
buf.copy_exactly(crate::cpu_set::mask_as_bytes(&mask))?;
Ok(size_of_val(&mask))
}
ContextHandle::SchedPolicy => {
let context = context.read(token.token());
let data = [context.sched_policy as u8, context.sched_rt_priority];
buf.copy_common_bytes_from_slice(&data)
}
ContextHandle::Name => {
let context = context.read(token.token());
let bytes = context.name.as_bytes();
let max = buf.len().min(bytes.len());
buf.copy_common_bytes_from_slice(&bytes[..max])
}
ContextHandle::Priority => {
let context = context.read(token.token());
let nice = (20 - context.prio as i32).clamp(-20, 19);
let data = nice.to_ne_bytes();
buf.copy_common_bytes_from_slice(&data)
} // TODO: Replace write() with SYS_SENDFD?
ContextHandle::Status { .. } => {
let status = {