Diff below, gypped from jmatthew@, allows us to see how much time CPUs
spend spinning on a mutex or on the KERNEL_LOCK().

On my sparc64 with 16 CPUs, top(1) now reports:

16  CPUs: 16.8% user,  0.0% nice,  9.2% sys, 49.4% spin,  0.1% intr, 24.5% idle

And systat(1) CPU view:

CPU            User         Nice      System        Spin   Interrupt        Idle
0              3.9%         0.0%        3.9%       74.5%        2.0%       15.7%
1              5.9%         0.0%       21.6%       72.5%        0.0%        0.0%
2              9.8%         0.0%        5.9%       84.3%        0.0%        0.0%
3              5.9%         0.0%        9.8%       82.4%        0.0%        2.0%
...
15             2.0%         0.0%       13.7%       56.9%        0.0%       27.5%

To keep it simple, systat(1) vmstat view now shows the spinning time instead
of the nice time.

I'd like to put something like that in, to be able to better understand
profiling and performance analysis.

Comments?  Oks?

Index: usr.bin/top/machine.c
===================================================================
RCS file: /cvs/src/usr.bin/top/machine.c,v
retrieving revision 1.89
diff -u -p -r1.89 machine.c
--- usr.bin/top/machine.c       30 May 2017 06:01:30 -0000      1.89
+++ usr.bin/top/machine.c       8 May 2018 14:51:28 -0000
@@ -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 */
Index: usr.bin/systat/vmstat.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/vmstat.c,v
retrieving revision 1.83
diff -u -p -r1.83 vmstat.c
--- usr.bin/systat/vmstat.c     3 May 2018 07:49:18 -0000       1.83
+++ usr.bin/systat/vmstat.c     8 May 2018 15:53:18 -0000
@@ -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;
Index: usr.bin/systat/cpu.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/cpu.c,v
retrieving revision 1.5
diff -u -p -r1.5 cpu.c
--- usr.bin/systat/cpu.c        2 Jan 2016 20:02:40 -0000       1.5
+++ usr.bin/systat/cpu.c        8 May 2018 15:43:23 -0000
@@ -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)                                       \
Index: sys/sys/sched.h
===================================================================
RCS file: /cvs/src/sys/sys/sched.h,v
retrieving revision 1.44
diff -u -p -r1.44 sched.h
--- sys/sys/sched.h     14 Dec 2017 23:21:04 -0000      1.44
+++ sys/sys/sched.h     8 May 2018 14:51:50 -0000
@@ -83,9 +83,10 @@
 #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. */
 
Index: sys/kern/kern_lock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_lock.c,v
retrieving revision 1.63
diff -u -p -r1.63 kern_lock.c
--- sys/kern/kern_lock.c        26 Apr 2018 06:51:48 -0000      1.63
+++ sys/kern/kern_lock.c        8 May 2018 14:23:20 -0000
@@ -117,6 +117,7 @@ __mp_lock_spin(struct __mp_lock *mpl, u_
        int nticks = __mp_lock_spinout;
 #endif
 
+       curcpu()->ci_spinning = 1;
        while (mpl->mpl_ticket != me) {
                CPU_BUSY_CYCLE();
 
@@ -128,6 +129,7 @@ __mp_lock_spin(struct __mp_lock *mpl, u_
                }
 #endif
        }
+       curcpu()->ci_spinning = 0;
 }
 
 void
@@ -261,6 +263,7 @@ __mtx_enter(struct mutex *mtx)
        int nticks = __mp_lock_spinout;
 #endif
 
+       curcpu()->ci_spinning = 1;
        while (__mtx_enter_try(mtx) == 0) {
                CPU_BUSY_CYCLE();
 
@@ -272,6 +275,7 @@ __mtx_enter(struct mutex *mtx)
                }
 #endif
        }
+       curcpu()->ci_spinning = 0;
 }
 
 int
Index: sys/kern/kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.93
diff -u -p -r1.93 kern_clock.c
--- sys/kern/kern_clock.c       22 Jul 2017 14:33:45 -0000      1.93
+++ sys/kern/kern_clock.c       8 May 2018 14:24:27 -0000
@@ -395,7 +395,9 @@ statclock(struct clockframe *frame)
                        if (p != NULL)
                                p->p_iticks++;
                        spc->spc_cp_time[CP_INTR]++;
-               } else if (p != NULL && p != spc->spc_idleproc) {
+               } else if (ci->ci_spinning)
+                       spc->spc_cp_time[CP_SPIN]++;
+               else if (p != NULL && p != spc->spc_idleproc) {
                        p->p_sticks++;
                        spc->spc_cp_time[CP_SYS]++;
                } else
Index: sys/arch/sparc64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/cpu.h,v
retrieving revision 1.92
diff -u -p -r1.92 cpu.h
--- sys/arch/sparc64/include/cpu.h      3 Dec 2017 10:55:50 -0000       1.92
+++ sys/arch/sparc64/include/cpu.h      8 May 2018 14:27:51 -0000
@@ -163,6 +163,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 #define CPUF_RUNNING   0x0001          /* CPU is running */
Index: sys/arch/sh/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sh/include/cpu.h,v
retrieving revision 1.27
diff -u -p -r1.27 cpu.h
--- sys/arch/sh/include/cpu.h   11 Jul 2014 10:53:07 -0000      1.27
+++ sys/arch/sh/include/cpu.h   8 May 2018 14:27:41 -0000
@@ -68,6 +68,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 extern struct cpu_info cpu_info_store;
Index: sys/arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.63
diff -u -p -r1.63 cpu.h
--- sys/arch/powerpc/include/cpu.h      7 May 2016 22:46:54 -0000       1.63
+++ sys/arch/powerpc/include/cpu.h      8 May 2018 14:27:26 -0000
@@ -91,6 +91,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 static __inline struct cpu_info *
Index: sys/arch/mips64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v
retrieving revision 1.124
diff -u -p -r1.124 cpu.h
--- sys/arch/mips64/include/cpu.h       24 Feb 2018 11:42:31 -0000      1.124
+++ sys/arch/mips64/include/cpu.h       8 May 2018 14:27:22 -0000
@@ -219,6 +219,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 #define        CPUF_PRIMARY    0x01            /* CPU is primary CPU */
Index: sys/arch/m88k/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/m88k/include/cpu.h,v
retrieving revision 1.65
diff -u -p -r1.65 cpu.h
--- sys/arch/m88k/include/cpu.h 19 Mar 2017 10:57:29 -0000      1.65
+++ sys/arch/m88k/include/cpu.h 8 May 2018 14:27:12 -0000
@@ -177,6 +177,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 extern cpuid_t master_cpu;
Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.162
diff -u -p -r1.162 cpu.h
--- sys/arch/i386/include/cpu.h 11 Apr 2018 15:44:08 -0000      1.162
+++ sys/arch/i386/include/cpu.h 8 May 2018 14:27:03 -0000
@@ -206,6 +206,8 @@ struct cpu_info {
        union vmm_cpu_cap       ci_vmm_cap;
        uint64_t                ci_vmxon_region_pa; /* Must be 64 bit */
        struct vmxon_region     *ci_vmxon_region;
+
+       volatile int    ci_spinning;
 };
 
 /*
Index: sys/arch/hppa/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v
retrieving revision 1.90
diff -u -p -r1.90 cpu.h
--- sys/arch/hppa/include/cpu.h 18 May 2017 15:41:59 -0000      1.90
+++ sys/arch/hppa/include/cpu.h 8 May 2018 14:26:53 -0000
@@ -112,6 +112,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 } __attribute__((__aligned__(64)));
 
 #define                CPUF_RUNNING    0x0001          /* CPU is running. */
Index: sys/arch/arm64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
retrieving revision 1.7
diff -u -p -r1.7 cpu.h
--- sys/arch/arm64/include/cpu.h        30 Jan 2018 15:46:12 -0000      1.7
+++ sys/arch/arm64/include/cpu.h        8 May 2018 14:26:46 -0000
@@ -124,6 +124,8 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam        *ci_gmon;
 #endif
+
+       volatile int    ci_spinning;
 };
 
 #define CPUF_PRIMARY           (1<<0)
Index: sys/arch/arm/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/cpu.h,v
retrieving revision 1.50
diff -u -p -r1.50 cpu.h
--- sys/arch/arm/include/cpu.h  26 Jan 2018 16:22:20 -0000      1.50
+++ sys/arch/arm/include/cpu.h  8 May 2018 14:26:38 -0000
@@ -209,6 +209,8 @@ struct cpu_info {
 #endif
 
        void (*ci_flush_bp)(void);
+
+       volatile int    ci_spinning;
 };
 
 extern struct cpu_info cpu_info_primary;
Index: sys/arch/amd64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v
retrieving revision 1.120
diff -u -p -r1.120 cpu.h
--- sys/arch/amd64/include/cpu.h        29 Mar 2018 01:21:02 -0000      1.120
+++ sys/arch/amd64/include/cpu.h        8 May 2018 14:22:21 -0000
@@ -204,6 +204,8 @@ struct cpu_info {
        union           vmm_cpu_cap ci_vmm_cap;
        paddr_t         ci_vmxon_region_pa;
        struct vmxon_region *ci_vmxon_region;
+
+       volatile int    ci_spinning;
 };
 
 #define CPUF_BSP       0x0001          /* CPU is the original BSP */
Index: sys/arch/alpha/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/alpha/include/cpu.h,v
retrieving revision 1.59
diff -u -p -r1.59 cpu.h
--- sys/arch/alpha/include/cpu.h        9 Apr 2018 04:11:04 -0000       1.59
+++ sys/arch/alpha/include/cpu.h        8 May 2018 14:26:27 -0000
@@ -212,6 +212,7 @@ struct cpu_info {
 #ifdef GPROF
        struct gmonparam *ci_gmon;
 #endif
+       volatile int    ci_spinning;
 };
 
 #define        CPUF_PRIMARY    0x01            /* CPU is primary CPU */

Reply via email to