Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Dec 1999 22:24:23 -0800
From:      Arun Sharma <adsharma@sharmas.dhs.org>
To:        freebsd-hackers@freebsd.org
Subject:   Per CPU timekeeping for SMP
Message-ID:  <19991205222423.A1391@sharmas.dhs.org>

next in thread | raw e-mail | index | archive | help

--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii

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

--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mp_cpu_time.patch"

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
 

--6TrnltStXW4iwmi0--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991205222423.A1391>