Here's a reimplementation of my earlier per cpu time keeping patch
on SMP.  The attached patch is against a 11/20/99 -current that I
cvsup'ed.

1. On UP, 

        sys_time is a global and contains the system wide stats
        cpu_time is a global and is essentially the same as sys_time.

2. On SMP

        sys_time contains the system wide stats
        cpu_time has been changed to a pointer in the per-cpu space.
        On BSP, this pointer points to a static array cpu0_cpu_time
        On APs, this space is kmem_alloc'ed

        Perhaps I should wrap cpu_time in a structure (cpu_info ?), which 
        could be the right place to store all per CPU info.

3. I've taken the liberty of changing CP_* to CPU_*. I hope the new names
   better convey the meaning of the variables and are acceptable.

4. I've gotten sysctls working for sys_time -

$ sysctl -A | grep kern.stats
kern.stats.systime.user: 25150
kern.stats.systime.nice: 3878
kern.stats.systime.sys: 14071
kern.stats.systime.intr: 7395
kern.stats.systime.idle: 5326029

I'm working on generating the per cpu sysctls. 

5. The machine specific code for Alpha will need some changes - which I
   can implement, but have no way of compiling or testing.

6. All the existing utilties which depended on peeking at cp_time will
   break (which is a good thing, IMO - so that I can fix them. :-) They 
   will all be converted to use sysctl, as time permits. 

Now, about the release schedule for this work - am I too late for the
12/15 feature freeze ? I'd appreciate some comments on the implementation,
so that if there are any issues, I can fix them before 12/15.

        -Arun
Index: i386/i386/genassym.c
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/i386/genassym.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 genassym.c
--- genassym.c  1999/11/20 23:46:06     1.1.1.4
+++ genassym.c  1999/12/05 19:45:42
@@ -205,6 +205,7 @@
        printf("#define\tGD_PRV_PADDR1 %#x\n", OS(globaldata, gd_prv_PADDR1));
        printf("#define\tPS_IDLESTACK %#x\n", OS(privatespace, idlestack));
        printf("#define\tPS_IDLESTACK_TOP %#x\n", sizeof(struct privatespace));
+       printf("#define\tGD_CPU_TIME %#x\n", OS(globaldata, gd_cpu_time));
 #endif
 
        printf("#define\tKCSEL %#x\n", GSEL(GCODE_SEL, SEL_KPL));
Index: i386/i386/globals.s
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/i386/globals.s,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 globals.s
--- globals.s   1999/08/31 05:12:09     1.1.1.2
+++ globals.s   1999/12/05 19:46:11
@@ -79,6 +79,7 @@
        .set    gd_currentldt,globaldata + GD_CURRENTLDT
 #endif
 
+
 #ifndef SMP
        .globl  _curproc, _curpcb, _npxproc
        .globl  _common_tss, _switchtime, _switchticks
@@ -122,6 +123,9 @@
        .set    gd_prv_CADDR2,globaldata + GD_PRV_CADDR2
        .set    gd_prv_CADDR3,globaldata + GD_PRV_CADDR3
        .set    gd_prv_PADDR1,globaldata + GD_PRV_PADDR1
+
+       .globl  gd_cpu_time
+       .set    gd_cpu_time,globaldata + GD_CPU_TIME
 #endif
 
 #if defined(SMP) || defined(APIC_IO)
Index: i386/i386/machdep.c
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/i386/machdep.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 machdep.c
--- machdep.c   1999/11/20 23:46:07     1.1.1.4
+++ machdep.c   1999/12/05 21:59:13
@@ -114,6 +114,7 @@
 #ifdef SMP
 #include <machine/smp.h>
 #include <machine/globaldata.h>
+#include <sys/dkstat.h>                        /* For cpu_time */
 #endif
 #ifdef PERFMON
 #include <machine/perfmon.h>
@@ -143,6 +144,10 @@
 
 static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf");
 
+#ifdef SMP
+static cpu0_cpu_time[NCPUSTATES];
+#endif
+
 int    _udatasel, _ucodesel;
 u_int  atdevbase;
 
@@ -1964,6 +1969,11 @@
        proc0.p_addr->u_pcb.pcb_mpnest = 1;
 #endif
        proc0.p_addr->u_pcb.pcb_ext = 0;
+
+#ifdef SMP
+       /* Setup cpu0's cpu_time */
+       cpu_time = &cpu0_cpu_time;
+#endif
 }
 
 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
Index: i386/i386/mp_machdep.c
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/i386/mp_machdep.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 mp_machdep.c
--- mp_machdep.c        1999/11/20 23:46:07     1.1.1.4
+++ mp_machdep.c        1999/12/05 19:48:29
@@ -243,6 +243,11 @@
 /** XXX FIXME: what system files declare these??? */
 extern struct region_descriptor r_gdt, r_idt;
 
+extern long sys_time[NCPUSTATES];
+#ifndef SMP
+extern long cpu_time[NCPUSTATES];
+#endif
+
 int    bsp_apic_ready = 0;     /* flags useability of BSP apic */
 int    mp_ncpus;               /* # of CPUs, including BSP */
 int    mp_naps;                /* # of Applications processors */
@@ -1798,6 +1803,9 @@
                SMPpt[pg + 3] = 0;              /* *prv_CMAP3 */
                SMPpt[pg + 4] = 0;              /* *prv_PMAP1 */
 
+               /* space for cpu time */
+               gd->gd_cpu_time = (long *) kmem_alloc(kernel_map, sizeof(long) 
+                                                      * NCPUSTATES);
                /* prime data page for it to use */
                gd->gd_cpuid = x;
                gd->gd_cpu_lockid = x << 24;
@@ -2222,8 +2230,6 @@
 int            checkstate_cpustate[NCPU];
 u_long         checkstate_pc[NCPU];
 
-extern long    cp_time[CPUSTATES];
-
 #define PC_TO_INDEX(pc, prof)                          \
         ((int)(((u_quad_t)((pc) - (prof)->pr_off) *    \
             (u_quad_t)((prof)->pr_scale)) >> 16) & ~1)
@@ -2272,10 +2278,13 @@
                if (pscnt > 1)
                        return;
                p->p_uticks++;
-               if (p->p_nice > NZERO)
-                       cp_time[CP_NICE]++;
-               else
-                       cp_time[CP_USER]++;
+               if (p->p_nice > NZERO) {
+                       cpu_time[CPU_NICE]++;
+                       sys_time[CPU_NICE]++;
+               } else {
+                       cpu_time[CPU_USER]++;
+                       sys_time[CPU_USER]++;
+               }
                break;
        case CHECKSTATE_SYS:
 #ifdef GPROF
@@ -2294,11 +2303,13 @@
                if (pscnt > 1)
                        return;
 
-               if (!p)
-                       cp_time[CP_IDLE]++;
-               else {
+               if (!p) {
+                       cpu_time[CPU_IDLE]++;
+                       sys_time[CPU_IDLE]++;
+               } else {
                        p->p_sticks++;
-                       cp_time[CP_SYS]++;
+                       cpu_time[CPU_SYS]++;
+                       sys_time[CPU_SYS]++;
                }
                break;
        case CHECKSTATE_INTR:
@@ -2320,7 +2331,7 @@
                        return;
                if (p)
                        p->p_iticks++;
-               cp_time[CP_INTR]++;
+               cpu_time[CPU_INTR]++;
        }
        if (p != NULL) {
                p->p_cpticks++;
Index: i386/include/globaldata.h
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/include/globaldata.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 globaldata.h
--- globaldata.h        1999/08/31 05:12:13     1.1.1.2
+++ globaldata.h        1999/12/05 19:45:30
@@ -26,6 +26,8 @@
  * $FreeBSD: src/sys/i386/include/globaldata.h,v 1.11 1999/08/28 00:44:12 peter Exp $
  */
 
+#include <sys/dkstat.h>
+
 /*
  * This structure maps out the global data that needs to be kept on a
  * per-cpu basis.  genassym uses this to generate offsets for the assembler
@@ -65,6 +67,7 @@
        caddr_t         gd_prv_CADDR2;
        caddr_t         gd_prv_CADDR3;
        unsigned        *gd_prv_PADDR1;
+       long            *gd_cpu_time;
 #endif
 };
 
Index: i386/include/globals.h
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/i386/include/globals.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 globals.h
--- globals.h   1999/08/31 05:12:13     1.1.1.2
+++ globals.h   1999/12/05 19:48:01
@@ -95,6 +95,7 @@
 #define        currentldt      GLOBAL_LVALUE(currentldt, int)
 #endif
 
+
 #ifdef SMP
 #define        cpuid           GLOBAL_RVALUE(cpuid, u_int)
 #define        other_cpus      GLOBAL_LVALUE(other_cpus, u_int)
@@ -107,6 +108,7 @@
 #define        prv_CADDR2      GLOBAL_RVALUE(prv_CADDR2, caddr_t)
 #define        prv_CADDR3      GLOBAL_RVALUE(prv_CADDR3, caddr_t)
 #define        prv_PADDR1      GLOBAL_RVALUE(prv_PADDR1, unsigned *)
+#define        cpu_time        GLOBAL_LVALUE(cpu_time, long *)
 #endif
 #endif /*UP kernel*/
 
@@ -123,6 +125,8 @@
 #ifdef USER_LDT
 GLOBAL_FUNC(currentldt)
 #endif
+
+GLOBAL_FUNC(cpu_time)
 
 #ifdef SMP
 GLOBAL_FUNC(cpuid)
Index: kern/kern_clock.c
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/kern/kern_clock.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 kern_clock.c
--- kern_clock.c        1999/11/20 23:46:37     1.1.1.4
+++ kern_clock.c        1999/12/05 22:00:34
@@ -70,6 +70,14 @@
 #include <machine/smp.h>
 #endif
 
+/* System wide statistics */
+long           sys_time[NCPUSTATES];
+
+#ifndef SMP
+/* In the SMP case, this is in the per cpu private page */
+long           cpu_time[NCPUSTATES];
+#endif
+
 /*
  * Number of timecounters used to implement stable storage
  */
@@ -87,13 +95,6 @@
 static void tco_setscales __P((struct timecounter *tc));
 static __inline unsigned tco_delta __P((struct timecounter *tc));
 
-/* Some of these don't belong here, but it's easiest to concentrate them. */
-#if defined(SMP) && defined(BETTER_CLOCK)
-long cp_time[CPUSTATES];
-#else
-static long cp_time[CPUSTATES];
-#endif
-
 long tk_cancc;
 long tk_nin;
 long tk_nout;
@@ -392,10 +393,14 @@
                 * If this process is being profiled record the tick.
                 */
                p->p_uticks++;
-               if (p->p_nice > NZERO)
-                       cp_time[CP_NICE]++;
-               else
-                       cp_time[CP_USER]++;
+               if (p->p_nice > NZERO) {
+                       cpu_time[CPU_NICE]++;
+                       sys_time[CPU_NICE]++;
+
+               } else {
+                       cpu_time[CPU_USER]++;
+                       sys_time[CPU_NICE]++;
+               }
        } else {
 #ifdef GPROF
                /*
@@ -432,12 +437,16 @@
                if (CLKF_INTR(frame)) {
                        if (p != NULL)
                                p->p_iticks++;
-                       cp_time[CP_INTR]++;
+                       cpu_time[CPU_INTR]++;
+                       sys_time[CPU_INTR]++;
                } else if (p != NULL) {
                        p->p_sticks++;
-                       cp_time[CP_SYS]++;
-               } else
-                       cp_time[CP_IDLE]++;
+                       cpu_time[CPU_SYS]++;
+                       sys_time[CPU_SYS]++;
+               } else {
+                       cpu_time[CPU_IDLE]++;
+                       sys_time[CPU_IDLE]++;
+               }
        }
        pscnt = psdiv;
 
Index: sys/dkstat.h
===================================================================
RCS file: /home/adsharma/cvs_root/freebsd-sys/sys/dkstat.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 dkstat.h
--- dkstat.h    1999/08/31 05:13:41     1.1.1.2
+++ dkstat.h    1999/12/05 07:28:40
@@ -42,12 +42,12 @@
 #ifndef _SYS_DKSTAT_H_
 #define _SYS_DKSTAT_H_ 1
 
-#define        CP_USER         0
-#define        CP_NICE         1
-#define        CP_SYS          2
-#define        CP_INTR         3
-#define        CP_IDLE         4
-#define        CPUSTATES       5
+#define        CPU_USER                0
+#define        CPU_NICE                1
+#define        CPU_SYS                 2
+#define        CPU_INTR                3
+#define        CPU_IDLE                4
+#define        NCPUSTATES              5
 
 #ifdef KERNEL
 

Reply via email to