From: Tim Leslie Subject: kern_resorce: move to lazy updates after donice To: "tech@openbsd.org" Date: Sat, 14 Feb 2026 13:18:31 +0000 @tech, Diff below to remove the immediate setpriority update loop in kern_resource. Currently, donice grabs ps_mtx and SCHED_LOCK to call setpriority on all threads. However, setpriority only updates p_usrpri; it does not move SRUN threads to their new runqueue buckets. That re-bucketing only happens in schedcpu (once per second). Since the scheduler doesn't act on the new priority until schedcpu anyway, there is no latency benefit to updating p_usrpri immediately for runnable threads. The other states are also covered: SSLEEP: Priority is recalculated in setrunnable upon wakeup. SONPROC: Priority is updated in schedclock (hardclock). As such, doing less is an improvement. WRITE_ONCE added to avoid any read tears. Tim diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -196,7 +197,6 @@ int donice(struct proc *curp, struct process *chgpr, int n) { struct ucred *ucred = curp->p_ucred; - struct proc *p; if (ucred->cr_uid != 0 && ucred->cr_ruid != 0 && ucred->cr_uid != chgpr->ps_ucred->cr_uid && @@ -209,14 +209,7 @@ donice(struct proc *curp, struct process *chgpr, int n) n += NZERO; if (n < chgpr->ps_nice && suser(curp)) return (EACCES); - chgpr->ps_nice = n; - mtx_enter(&chgpr->ps_mtx); - SCHED_LOCK(); - TAILQ_FOREACH(p, &chgpr->ps_threads, p_thr_link) { - setpriority(p, p->p_estcpu, n); - } - SCHED_UNLOCK(); - mtx_leave(&chgpr->ps_mtx); + WRITE_ONCE(chgpr->ps_nice, n); return (0); }