summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2018-05-14 12:31:22 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2018-05-14 12:31:22 +0000
commitca1cf5ebdbe3ffefe771df4b2ea17c999916b5b9 (patch)
tree67a8227617199c9082d4ed0b1734388cb7d0afa4
parent832b912d736e085430a113151047cf4410f2bb7b (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.c7
-rw-r--r--sys/kern/kern_lock.c8
-rw-r--r--sys/sys/sched.h21
-rw-r--r--usr.bin/systat/cpu.c29
-rw-r--r--usr.bin/systat/vmstat.c10
-rw-r--r--usr.bin/top/machine.c4
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 */