Index: kern/kern_clock.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/kern_clock.c,v retrieving revision 1.194 diff -u -r1.194 kern_clock.c --- kern/kern_clock.c 8 Mar 2007 06:44:33 -0000 1.194 +++ kern/kern_clock.c 20 May 2007 13:52:10 -0000 @@ -83,6 +83,9 @@ /* Some of these don't belong here, but it's easiest to concentrate them. */ long cp_time[CPUSTATES]; +/* Spin-lock protecting profiling statistics. */ +struct mtx time_lock; + static int sysctl_kern_cp_time(SYSCTL_HANDLER_ARGS) { @@ -172,6 +175,7 @@ * code do its bit. */ cpu_initclocks(); + mtx_init(&time_lock, "time lock", NULL, MTX_SPIN); /* * Compute profhz/stathz, and fix profhz if needed. @@ -349,20 +353,15 @@ register struct proc *p; { - /* - * XXX; Right now sched_lock protects statclock(), but perhaps - * it should be protected later on by a time_lock, which would - * cover psdiv, etc. as well. - */ PROC_LOCK_ASSERT(p, MA_OWNED); if (p->p_flag & P_STOPPROF) return; if ((p->p_flag & P_PROFIL) == 0) { - mtx_lock_spin(&sched_lock); p->p_flag |= P_PROFIL; + mtx_lock_spin(&time_lock); if (++profprocs == 1) cpu_startprofclock(); - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&time_lock); } } @@ -385,11 +384,11 @@ } if ((p->p_flag & P_PROFIL) == 0) return; - mtx_lock_spin(&sched_lock); p->p_flag &= ~P_PROFIL; + mtx_lock_spin(&time_lock); if (--profprocs == 0) cpu_stopprofclock(); - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&time_lock); } } @@ -412,7 +411,6 @@ td = curthread; p = td->td_proc; - mtx_lock_spin_flags(&sched_lock, MTX_QUIET); if (usermode) { /* * Charge the time as appropriate. @@ -422,6 +420,7 @@ thread_statclock(1); #endif td->td_uticks++; + mtx_lock_spin_flags(&time_lock, MTX_QUIET); if (p->p_nice > NZERO) cp_time[CP_NICE]++; else @@ -442,6 +441,7 @@ if ((td->td_pflags & TDP_ITHREAD) || td->td_intr_nesting_level >= 2) { td->td_iticks++; + mtx_lock_spin_flags(&time_lock, MTX_QUIET); cp_time[CP_INTR]++; } else { #ifdef KSE @@ -450,15 +450,18 @@ #endif td->td_pticks++; td->td_sticks++; + mtx_lock_spin_flags(&time_lock, MTX_QUIET); if (!TD_IS_IDLETHREAD(td)) cp_time[CP_SYS]++; else cp_time[CP_IDLE]++; } } + mtx_unlock_spin_flags(&time_lock, MTX_QUIET); CTR4(KTR_SCHED, "statclock: %p(%s) prio %d stathz %d", td, td->td_proc->p_comm, td->td_priority, (stathz)?stathz:hz); + mtx_lock_spin_flags(&sched_lock, MTX_QUIET); sched_clock(td); /* Update resource usage integrals and maximums. */ Index: kern/subr_prof.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/subr_prof.c,v retrieving revision 1.77 diff -u -r1.77 subr_prof.c --- kern/subr_prof.c 4 Mar 2007 22:36:46 -0000 1.77 +++ kern/subr_prof.c 20 May 2007 13:52:14 -0000 @@ -423,12 +423,12 @@ } PROC_LOCK(p); upp = &td->td_proc->p_stats->p_prof; - mtx_lock_spin(&sched_lock); + mtx_lock_spin(&time_lock); upp->pr_off = uap->offset; upp->pr_scale = uap->scale; upp->pr_base = uap->samples; upp->pr_size = uap->size; - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&time_lock); startprofclock(p); PROC_UNLOCK(p); @@ -468,15 +468,15 @@ if (ticks == 0) return; prof = &td->td_proc->p_stats->p_prof; - mtx_lock_spin(&sched_lock); + mtx_lock_spin(&time_lock); if (pc < prof->pr_off || (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) { - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&time_lock); return; /* out of range; ignore */ } addr = prof->pr_base + i; - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&time_lock); if ((v = fuswintr(addr)) == -1 || suswintr(addr, v + ticks) == -1) { td->td_profil_addr = pc; td->td_profil_ticks = ticks; Index: kern/subr_witness.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/subr_witness.c,v retrieving revision 1.230 diff -u -r1.230 subr_witness.c --- kern/subr_witness.c 19 Apr 2007 08:02:51 -0000 1.230 +++ kern/subr_witness.c 20 May 2007 13:52:18 -0000 @@ -410,6 +410,7 @@ { "callout", &lock_class_mtx_spin }, { "entropy harvest mutex", &lock_class_mtx_spin }, { "syscons video lock", &lock_class_mtx_spin }, + { "time lock", &lock_class_mtx_spin }, /* * leaf locks */ Index: sys/systm.h =================================================================== RCS file: /usr/home/ncvs/src/sys/sys/systm.h,v retrieving revision 1.255 diff -u -r1.255 systm.h --- sys/systm.h 8 Apr 2007 23:54:01 -0000 1.255 +++ sys/systm.h 20 May 2007 13:52:21 -0000 @@ -71,6 +71,8 @@ extern int maxusers; /* system tune hint */ +extern struct mtx time_lock; /* time lock for profiling */ + #ifdef INVARIANTS /* The option is always available */ #define KASSERT(exp,msg) do { \ if (__predict_false(!(exp))) \