diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-05-14 12:31:22 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-05-14 12:31:22 +0000 |
commit | ca1cf5ebdbe3ffefe771df4b2ea17c999916b5b9 (patch) | |
tree | 67a8227617199c9082d4ed0b1734388cb7d0afa4 | |
parent | 832b912d736e085430a113151047cf4410f2bb7b (diff) |
Stopping counting and reporting CPU time spent spinning on a lock as
system time.
Introduce a new CP_SPIN "scheduler state" and modify userland tools
to display the % of timer a CPU spents spinning.
Based on a diff from jmatthew@, ok pirofti@, bluhm@, visa@, deraadt@
-rw-r--r-- | sys/kern/kern_clock.c | 7 | ||||
-rw-r--r-- | sys/kern/kern_lock.c | 8 | ||||
-rw-r--r-- | sys/sys/sched.h | 21 | ||||
-rw-r--r-- | usr.bin/systat/cpu.c | 29 | ||||
-rw-r--r-- | usr.bin/systat/vmstat.c | 10 | ||||
-rw-r--r-- | usr.bin/top/machine.c | 4 |
6 files changed, 44 insertions, 35 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 2aef10f72c5..d77a4191d8c 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.93 2017/07/22 14:33:45 kettenis Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.94 2018/05/14 12:31:21 mpi Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -381,6 +381,7 @@ statclock(struct clockframe *frame) return; /* * Came from kernel mode, so we were: + * - spinning on a lock * - handling an interrupt, * - doing syscall or trap work on behalf of the current * user process, or @@ -391,7 +392,9 @@ statclock(struct clockframe *frame) * so that we know how much of its real time was spent * in ``non-process'' (i.e., interrupt) work. */ - if (CLKF_INTR(frame)) { + if (spc->spc_spinning) + spc->spc_cp_time[CP_SPIN]++; + else if (CLKF_INTR(frame)) { if (p != NULL) p->p_iticks++; spc->spc_cp_time[CP_INTR]++; diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index e1a8adc59a7..657e028d4c5 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_lock.c,v 1.63 2018/04/26 06:51:48 mpi Exp $ */ +/* $OpenBSD: kern_lock.c,v 1.64 2018/05/14 12:31:21 mpi Exp $ */ /* * Copyright (c) 2017 Visa Hankala @@ -113,10 +113,12 @@ ___mp_lock_init(struct __mp_lock *mpl, struct lock_type *type) static __inline void __mp_lock_spin(struct __mp_lock *mpl, u_int me) { + struct schedstate_percpu *spc = &curcpu()->ci_schedstate; #ifdef MP_LOCKDEBUG int nticks = __mp_lock_spinout; #endif + spc->spc_spinning++; while (mpl->mpl_ticket != me) { CPU_BUSY_CYCLE(); @@ -128,6 +130,7 @@ __mp_lock_spin(struct __mp_lock *mpl, u_int me) } #endif } + spc->spc_spinning--; } void @@ -257,10 +260,12 @@ __mtx_init(struct mutex *mtx, int wantipl) void __mtx_enter(struct mutex *mtx) { + struct schedstate_percpu *spc = &curcpu()->ci_schedstate; #ifdef MP_LOCKDEBUG int nticks = __mp_lock_spinout; #endif + spc->spc_spinning++; while (__mtx_enter_try(mtx) == 0) { CPU_BUSY_CYCLE(); @@ -272,6 +277,7 @@ __mtx_enter(struct mutex *mtx) } #endif } + spc->spc_spinning--; } int diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 698eda820a0..a8b39ec11f0 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.44 2017/12/14 23:21:04 dlg Exp $ */ +/* $OpenBSD: sched.h,v 1.45 2018/05/14 12:31:21 mpi Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -83,17 +83,20 @@ #define CP_USER 0 #define CP_NICE 1 #define CP_SYS 2 -#define CP_INTR 3 -#define CP_IDLE 4 -#define CPUSTATES 5 +#define CP_SPIN 3 +#define CP_INTR 4 +#define CP_IDLE 5 +#define CPUSTATES 6 #define SCHED_NQS 32 /* 32 run queues. */ /* * Per-CPU scheduler state. - * XXX - expose to userland for now. */ struct schedstate_percpu { + struct proc *spc_idleproc; /* idle proc for this cpu */ + TAILQ_HEAD(prochead, proc) spc_qs[SCHED_NQS]; + LIST_HEAD(,proc) spc_deadproc; struct timespec spc_runtime; /* time curproc started running */ volatile int spc_schedflags; /* flags; see below */ u_int spc_schedticks; /* ticks for schedclock() */ @@ -102,18 +105,12 @@ struct schedstate_percpu { int spc_rrticks; /* ticks until roundrobin() */ int spc_pscnt; /* prof/stat counter */ int spc_psdiv; /* prof/stat divisor */ - struct proc *spc_idleproc; /* idle proc for this cpu */ u_int spc_nrun; /* procs on the run queues */ fixpt_t spc_ldavg; /* shortest load avg. for this cpu */ - TAILQ_HEAD(prochead, proc) spc_qs[SCHED_NQS]; volatile uint32_t spc_whichqs; - -#ifdef notyet - struct proc *spc_reaper; /* dead proc reaper */ -#endif - LIST_HEAD(,proc) spc_deadproc; + volatile u_int spc_spinning; /* this cpu is currently spinning */ }; #ifdef _KERNEL diff --git a/usr.bin/systat/cpu.c b/usr.bin/systat/cpu.c index 90cdeeed6c2..ac7e2ba000e 100644 --- a/usr.bin/systat/cpu.c +++ b/usr.bin/systat/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.5 2016/01/02 20:02:40 benno Exp $ */ +/* $OpenBSD: cpu.c,v 1.6 2018/05/14 12:31:21 mpi Exp $ */ /* * Copyright (c) 2013 Reyk Floeter <reyk@openbsd.org> @@ -68,21 +68,23 @@ field_def fields_cpu[] = { { "User", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, { "Nice", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, { "System", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, + { "Spin", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, { "Interrupt", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, { "Idle", 10, 20, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0 }, }; #define FLD_CPU_CPU FIELD_ADDR(fields_cpu, 0) -#define FLD_CPU_INT FIELD_ADDR(fields_cpu, 1) -#define FLD_CPU_SYS FIELD_ADDR(fields_cpu, 2) -#define FLD_CPU_USR FIELD_ADDR(fields_cpu, 3) -#define FLD_CPU_NIC FIELD_ADDR(fields_cpu, 4) -#define FLD_CPU_IDLE FIELD_ADDR(fields_cpu, 5) +#define FLD_CPU_USR FIELD_ADDR(fields_cpu, 1) +#define FLD_CPU_NIC FIELD_ADDR(fields_cpu, 2) +#define FLD_CPU_SYS FIELD_ADDR(fields_cpu, 3) +#define FLD_CPU_SPIN FIELD_ADDR(fields_cpu, 4) +#define FLD_CPU_INT FIELD_ADDR(fields_cpu, 5) +#define FLD_CPU_IDLE FIELD_ADDR(fields_cpu, 6) /* Define views */ field_def *view_cpu_0[] = { - FLD_CPU_CPU, - FLD_CPU_INT, FLD_CPU_SYS, FLD_CPU_USR, FLD_CPU_NIC, FLD_CPU_IDLE, NULL + FLD_CPU_CPU, FLD_CPU_USR, FLD_CPU_NIC, FLD_CPU_SYS, FLD_CPU_SPIN, + FLD_CPU_INT, FLD_CPU_IDLE, NULL }; /* Define view managers */ @@ -232,11 +234,12 @@ initcpu(void) do { \ if (cur >= dispstart && cur < end) { \ print_fld_size(FLD_CPU_CPU, (v)); \ - print_fld_percentage(FLD_CPU_INT, (cs[0])); \ - print_fld_percentage(FLD_CPU_SYS, (cs[1])); \ - print_fld_percentage(FLD_CPU_USR, (cs[2])); \ - print_fld_percentage(FLD_CPU_NIC, (cs[3])); \ - print_fld_percentage(FLD_CPU_IDLE, (cs[4])); \ + print_fld_percentage(FLD_CPU_USR, (cs[CP_USER]));\ + print_fld_percentage(FLD_CPU_NIC, (cs[CP_NICE]));\ + print_fld_percentage(FLD_CPU_SYS, (cs[CP_SYS]));\ + print_fld_percentage(FLD_CPU_SPIN, (cs[CP_SPIN]));\ + print_fld_percentage(FLD_CPU_INT, (cs[CP_INTR]));\ + print_fld_percentage(FLD_CPU_IDLE, (cs[CP_IDLE])); \ end_line(); \ } \ if (++cur >= end) \ diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c index a515b73f958..13feb293b6e 100644 --- a/usr.bin/systat/vmstat.c +++ b/usr.bin/systat/vmstat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmstat.c,v 1.83 2018/05/03 07:49:18 otto Exp $ */ +/* $OpenBSD: vmstat.c,v 1.84 2018/05/14 12:31:21 mpi Exp $ */ /* $NetBSD: vmstat.c,v 1.5 1996/05/10 23:16:40 thorpej Exp $ */ /*- @@ -268,7 +268,7 @@ labelkre(void) mvprintw(GENSTATROW, GENSTATCOL, " Csw Trp Sys Int Sof Flt"); mvprintw(GRAPHROW, GRAPHCOL, - " . %%Int . %%Sys . %%Usr . %%Nic . %%Idle"); + " . %%Int . %%Sys . %%Usr . %%Spn . %%Idle"); mvprintw(PROCSROW, PROCSCOL, "Proc:r d s w"); mvprintw(GRAPHROW + 1, GRAPHCOL, "| | | | | | | | | | |"); @@ -306,8 +306,8 @@ labelkre(void) } while (0) #define MAXFAIL 5 -static char cpuchar[CPUSTATES] = { '|', '=', '>', '-', ' ' }; -static char cpuorder[CPUSTATES] = { CP_INTR, CP_SYS, CP_USER, CP_NICE, CP_IDLE }; +static char cpuchar[] = { '|', '=', '>', '-', ' ' }; +static char cpuorder[] = { CP_INTR, CP_SYS, CP_USER, CP_SPIN, CP_IDLE }; void showkre(void) @@ -367,7 +367,7 @@ showkre(void) psiz = 0; f2 = 0.0; - for (c = 0; c < CPUSTATES; c++) { + for (c = 0; c < nitems(cpuorder); c++) { i = cpuorder[c]; f1 = cputime(i); f2 += f1; diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index 0b4d5d7e748..4643778a15c 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machine.c,v 1.89 2017/05/30 06:01:30 tedu Exp $ */ +/* $OpenBSD: machine.c,v 1.90 2018/05/14 12:31:21 mpi Exp $ */ /*- * Copyright (c) 1994 Thorsten Lockert <tholo@sigmasoft.com> @@ -108,7 +108,7 @@ char *procstatenames[] = { /* these are for detailing the cpu states */ int64_t *cpu_states; char *cpustatenames[] = { - "user", "nice", "system", "interrupt", "idle", NULL + "user", "nice", "sys", "spin", "intr", "idle", NULL }; /* these are for detailing the memory statistics */ |