Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_racct.c
Show First 20 Lines • Show All 1,208 Lines • ▼ Show 20 Lines | ui_racct_foreach(racct_decay_callback, racct_decay_pre, | ||||
racct_decay_post, NULL, NULL); | racct_decay_post, NULL, NULL); | ||||
loginclass_racct_foreach(racct_decay_callback, racct_decay_pre, | loginclass_racct_foreach(racct_decay_callback, racct_decay_pre, | ||||
racct_decay_post, NULL, NULL); | racct_decay_post, NULL, NULL); | ||||
prison_racct_foreach(racct_decay_callback, racct_decay_pre, | prison_racct_foreach(racct_decay_callback, racct_decay_pre, | ||||
racct_decay_post, NULL, NULL); | racct_decay_post, NULL, NULL); | ||||
} | } | ||||
static void | static void | ||||
racctd(void) | _racctd(void) | ||||
{ | { | ||||
struct thread *td; | struct thread *td; | ||||
struct proc *p; | struct proc *p; | ||||
struct timeval wallclock; | struct timeval wallclock; | ||||
uint64_t pct, pct_estimate, runtime; | uint64_t pct, pct_estimate, runtime; | ||||
ASSERT_RACCT_ENABLED(); | sx_slock(&V_allproc_lock); | ||||
for (;;) { | LIST_FOREACH(p, &V_zombproc, p_list) { | ||||
racct_decay(); | |||||
sx_slock(&allproc_lock); | |||||
LIST_FOREACH(p, &zombproc, p_list) { | |||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
racct_set(p, RACCT_PCTCPU, 0); | racct_set(p, RACCT_PCTCPU, 0); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (p->p_state != PRS_NORMAL) { | if (p->p_state != PRS_NORMAL) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
continue; | continue; | ||||
} | } | ||||
microuptime(&wallclock); | microuptime(&wallclock); | ||||
timevalsub(&wallclock, &p->p_stats->p_start); | timevalsub(&wallclock, &p->p_stats->p_start); | ||||
PROC_STATLOCK(p); | PROC_STATLOCK(p); | ||||
FOREACH_THREAD_IN_PROC(p, td) | FOREACH_THREAD_IN_PROC(p, td) | ||||
ruxagg(p, td); | ruxagg(p, td); | ||||
runtime = cputick2usec(p->p_rux.rux_runtime); | runtime = cputick2usec(p->p_rux.rux_runtime); | ||||
PROC_STATUNLOCK(p); | PROC_STATUNLOCK(p); | ||||
#ifdef notyet | #ifdef notyet | ||||
KASSERT(runtime >= p->p_prev_runtime, | KASSERT(runtime >= p->p_prev_runtime, | ||||
("runtime < p_prev_runtime")); | ("runtime < p_prev_runtime")); | ||||
#else | #else | ||||
if (runtime < p->p_prev_runtime) | if (runtime < p->p_prev_runtime) | ||||
runtime = p->p_prev_runtime; | runtime = p->p_prev_runtime; | ||||
#endif | #endif | ||||
p->p_prev_runtime = runtime; | p->p_prev_runtime = runtime; | ||||
if (wallclock.tv_sec > 0 || wallclock.tv_usec > 0) { | if (wallclock.tv_sec > 0 || wallclock.tv_usec > 0) { | ||||
pct_estimate = (1000000 * runtime * 100) / | pct_estimate = (1000000 * runtime * 100) / | ||||
((uint64_t)wallclock.tv_sec * 1000000 + | ((uint64_t)wallclock.tv_sec * 1000000 + | ||||
wallclock.tv_usec); | wallclock.tv_usec); | ||||
} else | } else | ||||
pct_estimate = 0; | pct_estimate = 0; | ||||
pct = racct_getpcpu(p, pct_estimate); | pct = racct_getpcpu(p, pct_estimate); | ||||
RACCT_LOCK(); | RACCT_LOCK(); | ||||
#ifdef RCTL | #ifdef RCTL | ||||
rctl_throttle_decay(p->p_racct, RACCT_READBPS); | rctl_throttle_decay(p->p_racct, RACCT_READBPS); | ||||
rctl_throttle_decay(p->p_racct, RACCT_WRITEBPS); | rctl_throttle_decay(p->p_racct, RACCT_WRITEBPS); | ||||
rctl_throttle_decay(p->p_racct, RACCT_READIOPS); | rctl_throttle_decay(p->p_racct, RACCT_READIOPS); | ||||
rctl_throttle_decay(p->p_racct, RACCT_WRITEIOPS); | rctl_throttle_decay(p->p_racct, RACCT_WRITEIOPS); | ||||
#endif | #endif | ||||
racct_set_locked(p, RACCT_PCTCPU, pct, 1); | racct_set_locked(p, RACCT_PCTCPU, pct, 1); | ||||
racct_set_locked(p, RACCT_CPU, runtime, 0); | racct_set_locked(p, RACCT_CPU, runtime, 0); | ||||
racct_set_locked(p, RACCT_WALLCLOCK, | racct_set_locked(p, RACCT_WALLCLOCK, | ||||
(uint64_t)wallclock.tv_sec * 1000000 + | (uint64_t)wallclock.tv_sec * 1000000 + | ||||
wallclock.tv_usec, 0); | wallclock.tv_usec, 0); | ||||
RACCT_UNLOCK(); | RACCT_UNLOCK(); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
/* | /* | ||||
* To ensure that processes are throttled in a fair way, we need | * To ensure that processes are throttled in a fair way, we need | ||||
* to iterate over all processes again and check the limits | * to iterate over all processes again and check the limits | ||||
* for %cpu resource only after ucred racct containers have been | * for %cpu resource only after ucred racct containers have been | ||||
* properly filled. | * properly filled. | ||||
*/ | */ | ||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (p->p_state != PRS_NORMAL) { | if (p->p_state != PRS_NORMAL) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
continue; | continue; | ||||
} | } | ||||
if (racct_pcpu_available(p) <= 0) { | if (racct_pcpu_available(p) <= 0) { | ||||
if (p->p_racct->r_resources[RACCT_PCTCPU] > | if (p->p_racct->r_resources[RACCT_PCTCPU] > | ||||
pcpu_threshold) | pcpu_threshold) | ||||
racct_proc_throttle(p, -1); | racct_proc_throttle(p, -1); | ||||
} else if (p->p_throttled == -1) { | } else if (p->p_throttled == -1) { | ||||
racct_proc_wakeup(p); | racct_proc_wakeup(p); | ||||
} | } | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
} | |||||
static void | |||||
racctd(void) | |||||
{ | |||||
VPS_ITERATOR_DECL(vps_iter); | |||||
ASSERT_RACCT_ENABLED(); | |||||
for (;;) { | |||||
racct_decay(); | |||||
VPS_LIST_RLOCK(); | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
_racctd(); | |||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
pause("-", hz); | pause("-", hz); | ||||
} | } | ||||
} | } | ||||
static struct kproc_desc racctd_kp = { | static struct kproc_desc racctd_kp = { | ||||
"racctd", | "racctd", | ||||
racctd, | racctd, | ||||
NULL | NULL | ||||
Show All 28 Lines |