Module Name: src Committed By: rmind Date: Sun Nov 24 21:58:38 UTC 2013
Modified Files: src/sys/ddb: db_cpu.c src/sys/kern: kern_cpu.c kern_runq.c src/sys/sys: cpu.h src/usr.bin/vmstat: vmstat.c Log Message: Remove cpu_queue (and thus eleminate another use of CIRCLEQ) by replacing its uses with cpu_infos array. Extra testing by christos@. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/ddb/db_cpu.c cvs rdiff -u -r1.60 -r1.61 src/sys/kern/kern_cpu.c cvs rdiff -u -r1.40 -r1.41 src/sys/kern/kern_runq.c cvs rdiff -u -r1.37 -r1.38 src/sys/sys/cpu.h cvs rdiff -u -r1.189 -r1.190 src/usr.bin/vmstat/vmstat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ddb/db_cpu.c diff -u src/sys/ddb/db_cpu.c:1.4 src/sys/ddb/db_cpu.c:1.5 --- src/sys/ddb/db_cpu.c:1.4 Sun Feb 20 10:24:45 2011 +++ src/sys/ddb/db_cpu.c Sun Nov 24 21:58:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: db_cpu.c,v 1.4 2011/02/20 10:24:45 hannken Exp $ */ +/* $NetBSD: db_cpu.c,v 1.5 2013/11/24 21:58:38 rmind Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: db_cpu.c,v 1.4 2011/02/20 10:24:45 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_cpu.c,v 1.5 2013/11/24 21:58:38 rmind Exp $"); #ifndef _KERNEL #include <stdbool.h> @@ -42,26 +42,30 @@ __KERNEL_RCSID(0, "$NetBSD: db_cpu.c,v 1 #include <ddb/ddb.h> -static struct cpu_info *head; -static void *head_addr; +static struct cpu_info **cpu_info_addr; + +static struct cpu_info * +db_cpu_index(u_int idx) +{ + db_addr_t slot_addr = (db_addr_t)(cpu_info_addr + idx); + struct cpu_info *ci; + + db_read_bytes(slot_addr, sizeof(ci), (char *)&ci); + return ci; +} struct cpu_info * db_cpu_first(void) { - - head = db_read_ptr("cpu_queue"); - (void) db_value_of_name("cpu_queue", (db_expr_t *)&head_addr); - return head; + db_value_of_name("cpu_infos", (db_expr_t *)&cpu_info_addr); + return db_cpu_index(0); } struct cpu_info * db_cpu_next(struct cpu_info *ci) { + u_int idx; - db_read_bytes((db_addr_t)&ci->ci_data.cpu_qchain.cqe_next, - sizeof(ci), (char *)&ci); - if (ci == head_addr) { - ci = NULL; - } - return ci; + db_read_bytes((db_addr_t)&ci->ci_index, sizeof(idx), (char *)&idx); + return db_cpu_index(idx + 1); } Index: src/sys/kern/kern_cpu.c diff -u src/sys/kern/kern_cpu.c:1.60 src/sys/kern/kern_cpu.c:1.61 --- src/sys/kern/kern_cpu.c:1.60 Thu Aug 22 19:50:55 2013 +++ src/sys/kern/kern_cpu.c Sun Nov 24 21:58:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_cpu.c,v 1.60 2013/08/22 19:50:55 drochner Exp $ */ +/* $NetBSD: kern_cpu.c,v 1.61 2013/11/24 21:58:38 rmind Exp $ */ /*- * Copyright (c) 2007, 2008, 2009, 2010, 2012 The NetBSD Foundation, Inc. @@ -56,7 +56,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.60 2013/08/22 19:50:55 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.61 2013/11/24 21:58:38 rmind Exp $"); #include "opt_cpu_ucode.h" #include "opt_compat_netbsd.h" @@ -112,15 +112,13 @@ int ncpu __read_mostly; int ncpuonline __read_mostly; bool mp_online __read_mostly; +/* An array of CPUs. There are ncpu entries. */ +struct cpu_info **cpu_infos __read_mostly; + /* Note: set on mi_cpu_attach() and idle_loop(). */ kcpuset_t * kcpuset_attached __read_mostly = NULL; kcpuset_t * kcpuset_running __read_mostly = NULL; -struct cpuqueue cpu_queue __cacheline_aligned - = CIRCLEQ_HEAD_INITIALIZER(cpu_queue); - -static struct cpu_info **cpu_infos __read_mostly; - /* * mi_cpu_init: early initialisation of MI CPU related structures. * @@ -153,7 +151,6 @@ mi_cpu_attach(struct cpu_info *ci) kcpuset_create(&ci->ci_data.cpu_kcpuset, true); kcpuset_set(ci->ci_data.cpu_kcpuset, cpu_index(ci)); - CIRCLEQ_INSERT_TAIL(&cpu_queue, ci, ci_data.cpu_qchain); TAILQ_INIT(&ci->ci_data.cpu_ld_locks); __cpu_simple_lock_init(&ci->ci_data.cpu_ld_lock); @@ -162,8 +159,8 @@ mi_cpu_attach(struct cpu_info *ci) cpu_index(ci)); if (__predict_false(cpu_infos == NULL)) { - cpu_infos = - kmem_zalloc(sizeof(cpu_infos[0]) * maxcpus, KM_SLEEP); + size_t nslots = maxcpus * sizeof(struct cpu_info *) + 1; + cpu_infos = kmem_zalloc(nslots, KM_SLEEP); } cpu_infos[cpu_index(ci)] = ci; Index: src/sys/kern/kern_runq.c diff -u src/sys/kern/kern_runq.c:1.40 src/sys/kern/kern_runq.c:1.41 --- src/sys/kern/kern_runq.c:1.40 Sat Oct 19 19:22:16 2013 +++ src/sys/kern/kern_runq.c Sun Nov 24 21:58:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_runq.c,v 1.40 2013/10/19 19:22:16 christos Exp $ */ +/* $NetBSD: kern_runq.c,v 1.41 2013/11/24 21:58:38 rmind Exp $ */ /* * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.40 2013/10/19 19:22:16 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.41 2013/11/24 21:58:38 rmind Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -365,7 +365,7 @@ sched_migratable(const struct lwp *l, st struct cpu_info * sched_takecpu(struct lwp *l) { - struct cpu_info *ci, *tci, *first, *next; + struct cpu_info *ci, *tci, *pivot, *next; struct schedstate_percpu *spc; runqueue_t *ci_rq, *ici_rq; pri_t eprio, lpri, pri; @@ -411,15 +411,18 @@ sched_takecpu(struct lwp *l) * Look for the CPU with the lowest priority thread. In case of * equal priority, choose the CPU with the fewest of threads. */ - first = l->l_cpu; - ci = first; - tci = first; + pivot = l->l_cpu; + ci = pivot; + tci = pivot; lpri = PRI_COUNT; do { - next = CIRCLEQ_LOOP_NEXT(&cpu_queue, ci, ci_data.cpu_qchain); + if ((next = cpu_lookup(cpu_index(ci) + 1)) == NULL) { + /* Reached the end, start from the beginning. */ + next = cpu_lookup(0); + } spc = &ci->ci_schedstate; ici_rq = spc->spc_sched_info; - pri = max(spc->spc_curpriority, spc->spc_maxpriority); + pri = MAX(spc->spc_curpriority, spc->spc_maxpriority); if (pri > lpri) continue; @@ -432,7 +435,7 @@ sched_takecpu(struct lwp *l) lpri = pri; tci = ci; ci_rq = ici_rq; - } while (ci = next, ci != first); + } while (ci = next, ci != pivot); ci_rq = tci->ci_schedstate.spc_sched_info; ci_rq->r_ev_push.ev_count++; Index: src/sys/sys/cpu.h diff -u src/sys/sys/cpu.h:1.37 src/sys/sys/cpu.h:1.38 --- src/sys/sys/cpu.h:1.37 Wed Oct 17 20:19:55 2012 +++ src/sys/sys/cpu.h Sun Nov 24 21:58:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.37 2012/10/17 20:19:55 drochner Exp $ */ +/* $NetBSD: cpu.h,v 1.38 2013/11/24 21:58:38 rmind Exp $ */ /*- * Copyright (c) 2007 YAMAMOTO Takashi, @@ -96,7 +96,7 @@ CIRCLEQ_HEAD(cpuqueue, cpu_info); #ifdef _KERNEL extern kmutex_t cpu_lock; extern u_int maxcpus; -extern struct cpuqueue cpu_queue; +extern struct cpu_info **cpu_infos; extern kcpuset_t *kcpuset_attached; extern kcpuset_t *kcpuset_running; Index: src/usr.bin/vmstat/vmstat.c diff -u src/usr.bin/vmstat/vmstat.c:1.189 src/usr.bin/vmstat/vmstat.c:1.190 --- src/usr.bin/vmstat/vmstat.c:1.189 Sun Nov 10 05:16:10 2013 +++ src/usr.bin/vmstat/vmstat.c Sun Nov 24 21:58:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.189 2013/11/10 05:16:10 mrg Exp $ */ +/* $NetBSD: vmstat.c,v 1.190 2013/11/24 21:58:38 rmind Exp $ */ /*- * Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; #else -__RCSID("$NetBSD: vmstat.c,v 1.189 2013/11/10 05:16:10 mrg Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.190 2013/11/24 21:58:38 rmind Exp $"); #endif #endif /* not lint */ @@ -139,15 +139,12 @@ __RCSID("$NetBSD: vmstat.c,v 1.189 2013/ struct cpu_info { struct cpu_data ci_data; }; -CIRCLEQ_HEAD(cpuqueue, cpu_info); -struct cpuqueue cpu_queue; - #else - # include <sys/cpu.h> -struct cpuqueue cpu_queue; - #endif + +struct cpu_info **cpu_infos; + /* * General namelist */ @@ -171,8 +168,8 @@ struct nlist namelist[] = { .n_name = "_time_second" }, #define X_TIME 8 { .n_name = "_time" }, -#define X_CPU_QUEUE 9 - { .n_name = "_cpu_queue" }, +#define X_CPU_INFOS 9 + { .n_name = "_cpu_infos" }, #define X_NL_SIZE 10 { .n_name = NULL }, }; @@ -733,7 +730,7 @@ dovmstat(struct timespec *interval, int if (!hz) kread(namelist, X_HZ, &hz, sizeof(hz)); - kread(namelist, X_CPU_QUEUE, &cpu_queue, sizeof(cpu_queue)); + kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); for (hdrcnt = 1;;) { if (!--hdrcnt) @@ -906,8 +903,9 @@ dosum(void) (void)printf("%9u swap pages in use\n", uvmexp.swpginuse); (void)printf("%9u swap allocations\n", uvmexp.nswget); - kread(namelist, X_CPU_QUEUE, &cpu_queue, sizeof(cpu_queue)); + kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); cpucounters(&cc); + (void)printf("%9" PRIu64 " total faults taken\n", cc.nfault); (void)printf("%9" PRIu64 " traps\n", cc.ntrap); (void)printf("%9" PRIu64 " device interrupts\n", cc.nintr); @@ -1028,28 +1026,31 @@ drvstats(int *ovflwp) void cpucounters(struct cpu_counter *cc) { - struct cpu_info *ci, *first = NULL; - (void)memset(cc, 0, sizeof(*cc)); - CIRCLEQ_FOREACH(ci, &cpu_queue, ci_data.cpu_qchain) { - struct cpu_info tci; + struct cpu_info **slot = cpu_infos; + + memset(cc, 0, sizeof(*cc)); + + for (;;) { + struct cpu_info tci, *ci = NULL; + + deref_kptr(slot++, &ci, sizeof(ci), "CPU array trashed"); + if (!ci) { + break; + } + if ((size_t)kvm_read(kd, (u_long)ci, &tci, sizeof(tci)) != sizeof(tci)) { - warnx("Can't read cpu info from %p (%s)", - ci, kvm_geterr(kd)); - (void)memset(cc, 0, sizeof(*cc)); - return; + warnx("Can't read cpu info from %p (%s)", + ci, kvm_geterr(kd)); + memset(cc, 0, sizeof(*cc)); + return; } - if (first == NULL) - first = tci.ci_data.cpu_qchain.cqe_prev; cc->nintr += tci.ci_data.cpu_nintr; cc->nsyscall += tci.ci_data.cpu_nsyscall; cc->nswtch = tci.ci_data.cpu_nswtch; cc->nfault = tci.ci_data.cpu_nfault; cc->ntrap = tci.ci_data.cpu_ntrap; cc->nsoft = tci.ci_data.cpu_nsoft; - ci = &tci; - if (tci.ci_data.cpu_qchain.cqe_next == first) - break; } }