Remove locking of p_stmutex from sched_pstats(), protect l_pctcpu with p_lock,

and make l_cpticks lock-less.  Should fix PR/38296.

Reviewed (slightly different version) by <ad>.
This commit is contained in:
rmind 2008-07-02 19:38:37 +00:00
parent 14071b7c24
commit 61fc86b29b
3 changed files with 30 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_clock.c,v 1.124 2008/06/01 21:24:15 ad Exp $ */
/* $NetBSD: kern_clock.c,v 1.125 2008/07/02 19:38:37 rmind Exp $ */
/*-
* Copyright (c) 2000, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.124 2008/06/01 21:24:15 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.125 2008/07/02 19:38:37 rmind Exp $");
#include "opt_ntp.h"
#include "opt_perfctrs.h"
@ -446,7 +446,7 @@ statclock(struct clockframe *frame)
spc->spc_pscnt = psdiv;
if (p != NULL) {
++l->l_cpticks;
atomic_inc_uint(&l->l_cpticks);
mutex_spin_exit(&p->p_stmutex);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_synch.c,v 1.248 2008/05/31 21:26:01 ad Exp $ */
/* $NetBSD: kern_synch.c,v 1.249 2008/07/02 19:38:37 rmind Exp $ */
/*-
* Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.248 2008/05/31 21:26:01 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.249 2008/07/02 19:38:37 rmind Exp $");
#include "opt_kstack.h"
#include "opt_perfctrs.h"
@ -1163,17 +1163,20 @@ fixpt_t ccpu = 0.95122942450071400909 * FSCALE; /* exp(-1/20) */
void
sched_pstats(void *arg)
{
const int clkhz = (stathz != 0 ? stathz : hz);
struct rlimit *rlim;
struct lwp *l;
struct proc *p;
int sig, clkhz;
long runtm;
fixpt_t lpctcpu;
u_int lcpticks;
int sig;
sched_pstats_ticks++;
mutex_enter(proc_lock);
PROCLIST_FOREACH(p, &allproc) {
if ((p->p_flag & PK_MARKER) != 0)
if (__predict_false((p->p_flag & PK_MARKER) != 0))
continue;
/*
@ -1182,10 +1185,9 @@ sched_pstats(void *arg)
* (remember them?) overflow takes 45 days.
*/
mutex_enter(p->p_lock);
mutex_spin_enter(&p->p_stmutex);
runtm = p->p_rtime.sec;
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
if ((l->l_flag & LW_IDLE) != 0)
if (__predict_false((l->l_flag & LW_IDLE) != 0))
continue;
lwp_lock(l);
runtm += l->l_rtime.sec;
@ -1193,27 +1195,26 @@ sched_pstats(void *arg)
sched_lwp_stats(l);
lwp_unlock(l);
/*
* p_pctcpu is only for ps.
*/
l->l_pctcpu = (l->l_pctcpu * ccpu) >> FSHIFT;
if (l->l_slptime < 1) {
clkhz = stathz != 0 ? stathz : hz;
if (l->l_slptime != 0)
continue;
lpctcpu = l->l_pctcpu;
lcpticks = atomic_swap_uint(&l->l_cpticks, 0);
#if (FSHIFT >= CCPU_SHIFT)
l->l_pctcpu += (clkhz == 100) ?
((fixpt_t)l->l_cpticks) <<
(FSHIFT - CCPU_SHIFT) :
100 * (((fixpt_t) p->p_cpticks)
<< (FSHIFT - CCPU_SHIFT)) / clkhz;
lpctcpu += (clkhz == 100) ?
((fixpt_t)lcpticks) <<
(FSHIFT - CCPU_SHIFT) :
100 * (((fixpt_t) p->p_cpticks)
<< (FSHIFT - CCPU_SHIFT)) / clkhz;
#else
l->l_pctcpu += ((FSCALE - ccpu) *
(l->l_cpticks * FSCALE / clkhz)) >> FSHIFT;
lpctcpu += ((FSCALE - ccpu) *
(lcpticks * FSCALE / clkhz)) >> FSHIFT;
#endif
l->l_cpticks = 0;
}
l->l_pctcpu = lpctcpu;
}
/* Calculating p_pctcpu only for ps(1) */
p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
mutex_spin_exit(&p->p_stmutex);
/*
* Check if the process exceeds its CPU resource allocation.
@ -1221,7 +1222,7 @@ sched_pstats(void *arg)
*/
rlim = &p->p_rlimit[RLIMIT_CPU];
sig = 0;
if (runtm >= rlim->rlim_cur) {
if (__predict_false(runtm >= rlim->rlim_cur)) {
if (runtm >= rlim->rlim_max)
sig = SIGKILL;
else {
@ -1231,7 +1232,7 @@ sched_pstats(void *arg)
}
}
mutex_exit(p->p_lock);
if (sig)
if (__predict_false(sig))
psignal(p, sig);
}
mutex_exit(proc_lock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lwp.h,v 1.102 2008/06/22 00:06:36 christos Exp $ */
/* $NetBSD: lwp.h,v 1.103 2008/07/02 19:38:37 rmind Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -57,7 +57,6 @@
* l: *l_mutex
* p: l_proc->p_lock
* s: spc_mutex, which may or may not be referenced by l_mutex
* t: l_proc->p_stmutex
* S: l_selcpu->sc_lock
* (: unlocked, stable
* !: unlocked, may only be reliably accessed by the LWP itself
@ -96,8 +95,8 @@ struct lwp {
SLIST_HEAD(, turnstile) l_pi_lenders; /* l: ts lending us priority */
uint64_t l_ncsw; /* l: total context switches */
uint64_t l_nivcsw; /* l: involuntary context switches */
int l_cpticks; /* t: Ticks of CPU time */
fixpt_t l_pctcpu; /* t: %cpu during l_swtime */
u_int l_cpticks; /* (: Ticks of CPU time */
fixpt_t l_pctcpu; /* p: %cpu during l_swtime */
fixpt_t l_estcpu; /* l: cpu time for SCHED_4BSD */
psetid_t l_psid; /* l: assigned processor-set ID */
struct cpu_info *l_target_cpu; /* l: target CPU to migrate */