Download raw body.
kern_resorce: move to lazy updates after donice
@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 <sys/ktrace.h>
#include <sys/sched.h>
#include <sys/signalvar.h>
+#include <sys/atomic.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
@@ -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);
}
kern_resorce: move to lazy updates after donice