From owner-freebsd-hackers Sun Dec 5 22:25:10 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from c62443-a.frmt1.sfba.home.com (c62443-a.frmt1.sfba.home.com [24.0.69.165]) by hub.freebsd.org (Postfix) with ESMTP id F0AE414D74 for ; Sun, 5 Dec 1999 22:25:00 -0800 (PST) (envelope-from adsharma@sharmas.dhs.org) Received: from sharmas.dhs.org (astra.sharmas.org [192.168.0.12]) by c62443-a.frmt1.sfba.home.com (8.9.3/8.9.3) with ESMTP id WAA23152 for ; Sun, 5 Dec 1999 22:24:55 -0800 Received: (from adsharma@localhost) by sharmas.dhs.org (8.9.3/8.9.3) id WAA01408 for freebsd-hackers@freebsd.org; Sun, 5 Dec 1999 22:24:23 -0800 (PST) (envelope-from adsharma) Date: Sun, 5 Dec 1999 22:24:23 -0800 From: Arun Sharma To: freebsd-hackers@freebsd.org Subject: Per CPU timekeeping for SMP Message-ID: <19991205222423.A1391@sharmas.dhs.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="6TrnltStXW4iwmi0" X-Mailer: Mutt 1.0i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --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 #include +#include /* For cpu_time */ #endif #ifdef PERFMON #include @@ -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 + /* * 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 #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