From owner-freebsd-bugs Fri May 12 23: 0:25 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id A622737BC03 for ; Fri, 12 May 2000 23:00:05 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id XAA99096; Fri, 12 May 2000 23:00:04 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from sharmas.dhs.org (c62443-a.frmt1.sfba.home.com [24.0.69.165]) by hub.freebsd.org (Postfix) with ESMTP id 94C8A37BC03 for ; Fri, 12 May 2000 22:50:17 -0700 (PDT) (envelope-from adsharma@sharmas.dhs.org) Received: (from adsharma@localhost) by sharmas.dhs.org (8.9.3/8.9.3) id WAA00677; Fri, 12 May 2000 22:48:43 -0700 (PDT) (envelope-from adsharma) Message-Id: <200005130548.WAA00677@sharmas.dhs.org> Date: Fri, 12 May 2000 22:48:43 -0700 (PDT) From: Arun Sharma Reply-To: adsharma@sharmas.dhs.org To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/18524: Per CPU time keeping on SMP Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 18524 >Category: kern >Synopsis: The current kernel doesn't keep stats on a per cpu basis >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri May 12 23:00:04 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Arun Sharma >Release: FreeBSD 4.0-STABLE i386 >Organization: Myself >Environment: 5.0-current >Description: The current kernel doesn't keep stats on a per cpu basis >How-To-Repeat: Run 5.0-current. >Fix: The attached patch creates the right variables within the kernel. The kld at http://sharmas.dhs.org/~adsharma/projects/freebsd/sysctl.tar.gz extracts them using a bunch of dynamic sysctls. Implementation details: 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. The machine specific code for Alpha will need some changes - which I can implement, but have no way of compiling or testing. 5. All the existing utilties which depended on peeking at cp_time will break (which is a good thing, IMO - so that they can be changed to use the new sysctl :-) 6. After the above kld is loaded, the sysctl's will be at kern.stats.* --- sys/i386/i386/genassym.c Fri May 5 02:58:01 2000 +++ sys.new/i386/i386/genassym.c Fri May 12 00:05:22 2000 @@ -197,6 +197,7 @@ ASSYM(GD_PRV_CADDR2, offsetof(struct globaldata, gd_prv_CADDR2)); ASSYM(GD_PRV_CADDR3, offsetof(struct globaldata, gd_prv_CADDR3)); ASSYM(GD_PRV_PADDR1, offsetof(struct globaldata, gd_prv_PADDR1)); +ASSYM(GD_CPU_TIME, offsetof(struct globaldata, gd_cpu_time)); ASSYM(PS_IDLESTACK, offsetof(struct privatespace, idlestack)); ASSYM(PS_IDLESTACK_TOP, sizeof(struct privatespace)); #endif --- sys/i386/i386/globals.s Mon Mar 27 23:16:15 2000 +++ sys.new/i386/i386/globals.s Fri May 12 00:05:55 2000 @@ -110,6 +110,7 @@ .globl gd_ss_eflags, gd_inside_intr .globl gd_prv_CMAP1, gd_prv_CMAP2, gd_prv_CMAP3, gd_prv_PMAP1 .globl gd_prv_CADDR1, gd_prv_CADDR2, gd_prv_CADDR3, gd_prv_PADDR1 + .globl gd_cpu_time .set gd_cpuid,globaldata + GD_CPUID .set gd_cpu_lockid,globaldata + GD_CPU_LOCKID @@ -124,6 +125,7 @@ .set gd_prv_CADDR2,globaldata + GD_PRV_CADDR2 .set gd_prv_CADDR3,globaldata + GD_PRV_CADDR3 .set gd_prv_PADDR1,globaldata + GD_PRV_PADDR1 + .set gd_cpu_time,globaldata + GD_CPU_TIME #endif #if defined(SMP) || defined(APIC_IO) --- sys/i386/i386/machdep.c Fri May 5 02:58:02 2000 +++ sys.new/i386/i386/machdep.c Fri May 12 00:06:37 2000 @@ -102,6 +102,7 @@ #ifdef SMP #include #include +#include #endif #ifdef PERFMON #include @@ -131,6 +132,10 @@ static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf"); +#ifdef SMP +static cpu0_cpu_time[NCPUSTATES]; +#endif + int _udatasel, _ucodesel; u_int atdevbase; @@ -1986,6 +1991,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) --- sys/i386/i386/mp_machdep.c Mon Mar 27 23:16:15 2000 +++ sys.new/i386/i386/mp_machdep.c Fri May 12 22:10:48 2000 @@ -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 */ @@ -1862,6 +1867,10 @@ 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; @@ -2286,8 +2295,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) @@ -2336,10 +2343,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_NICE]++; + } break; case CHECKSTATE_SYS: #ifdef GPROF @@ -2358,11 +2368,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: @@ -2384,7 +2396,8 @@ return; if (p) p->p_iticks++; - cp_time[CP_INTR]++; + cpu_time[CPU_INTR]++; + sys_time[CPU_INTR]++; } if (p != NULL) { schedclock(p); --- sys/i386/include/globaldata.h Mon Mar 27 23:16:20 2000 +++ sys.new/i386/include/globaldata.h Fri May 12 00:11:42 2000 @@ -65,6 +65,7 @@ caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR3; unsigned *gd_prv_PADDR1; + long *gd_cpu_time; #endif u_int gd_astpending; }; --- sys/i386/include/globals.h Mon Mar 27 23:16:21 2000 +++ sys.new/i386/include/globals.h Fri May 12 00:13:18 2000 @@ -108,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*/ @@ -125,6 +126,8 @@ #ifdef USER_LDT GLOBAL_FUNC(currentldt) #endif + +GLOBAL_FUNC(cpu_time) #ifdef SMP GLOBAL_FUNC(cpuid) --- sys/kern/kern_clock.c Wed Apr 19 07:57:51 2000 +++ sys.new/kern/kern_clock.c Fri May 12 22:06:44 2000 @@ -69,11 +69,12 @@ static void initclocks __P((void *dummy)); SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL) -/* 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]; +/* 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 long tk_cancc; @@ -343,10 +344,13 @@ * Charge the time as appropriate. */ 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]++; + } } else { #ifdef GPROF /* @@ -383,12 +387,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; --- sys/sys/dkstat.h Tue Dec 28 20:24:40 1999 +++ sys.new/sys/dkstat.h Fri May 12 22:04:50 2000 @@ -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 >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message