svn commit: r200431 - in stable/8/sys/ia64: ia64 include

Marcel Moolenaar marcel at FreeBSD.org
Fri Dec 11 21:14:41 PST 2009


Author: marcel
Date: Sat Dec 12 05:14:40 2009
New Revision: 200431
URL: http://svn.freebsd.org/changeset/base/200431

Log:
  MFC rev 199893, 199941, 200200 and 200207:
  o   Eliminate MAXCPU.
  o   Revamp the PCPU structure.

Modified:
  stable/8/sys/ia64/ia64/clock.c
  stable/8/sys/ia64/ia64/genassym.c
  stable/8/sys/ia64/ia64/interrupt.c
  stable/8/sys/ia64/ia64/machdep.c
  stable/8/sys/ia64/ia64/mp_machdep.c
  stable/8/sys/ia64/ia64/pmap.c
  stable/8/sys/ia64/include/kdb.h
  stable/8/sys/ia64/include/param.h
  stable/8/sys/ia64/include/pcpu.h
  stable/8/sys/ia64/include/pmap.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/ia64/ia64/clock.c
==============================================================================
--- stable/8/sys/ia64/ia64/clock.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/clock.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -64,9 +64,9 @@ void
 pcpu_initclock(void)
 {
 
-	PCPU_SET(clockadj, 0);
-	PCPU_SET(clock, ia64_get_itc());
-	ia64_set_itm(PCPU_GET(clock) + ia64_clock_reload);
+	PCPU_SET(md.clockadj, 0);
+	PCPU_SET(md.clock, ia64_get_itc());
+	ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
 	ia64_set_itv(CLOCK_VECTOR);	/* highest priority class */
 	ia64_srlz_d();
 }

Modified: stable/8/sys/ia64/ia64/genassym.c
==============================================================================
--- stable/8/sys/ia64/ia64/genassym.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/genassym.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -91,7 +91,7 @@ ASSYM(MC_SPECIAL_RNAT,	offsetof(mcontext
 ASSYM(PAGE_SHIFT,	PAGE_SHIFT);
 ASSYM(PAGE_SIZE,	PAGE_SIZE);
 
-ASSYM(PC_CURRENT_PMAP,	offsetof(struct pcpu, pc_current_pmap));
+ASSYM(PC_CURRENT_PMAP,	offsetof(struct pcpu, pc_md.current_pmap));
 ASSYM(PC_CURTHREAD,	offsetof(struct pcpu, pc_curthread));
 ASSYM(PC_IDLETHREAD,	offsetof(struct pcpu, pc_idlethread));
 

Modified: stable/8/sys/ia64/ia64/interrupt.c
==============================================================================
--- stable/8/sys/ia64/ia64/interrupt.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/interrupt.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -84,28 +84,6 @@ dummy_perf(unsigned long vector, struct 
 
 void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf;
 
-static unsigned int ints[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU",
-    "");
-
-static unsigned int clks[MAXCPU];
-#ifdef SMP
-SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU",
-    "");
-#else
-SYSCTL_INT(_debug, OID_AUTO, clks, CTLFLAG_RW, clks, 0, "");
-#endif
-
-#ifdef SMP
-static unsigned int asts[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU",
-    "");
-
-static unsigned int rdvs[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU",
-    "");
-#endif
-
 SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
 
 static int adjust_edges = 0;
@@ -139,6 +117,8 @@ interrupt(struct trapframe *tf)
 
 	td = curthread;
 
+	PCPU_INC(cnt.v_intr);
+
 	vector = tf->tf_special.ifa;
 
  next:
@@ -149,33 +129,35 @@ interrupt(struct trapframe *tf)
 	 * to add it to this switch-like construct.
 	 */
 	if (vector == 0) {
+		PCPU_INC(md.stats.pcs_nextints);
 		inta = ib->ib_inta;
-		printf("ExtINT interrupt: vector=%u\n", (int)inta);
 		if (inta == 15) {
+			PCPU_INC(md.stats.pcs_nstrays);
 			__asm __volatile("mov cr.eoi = r0;; srlz.d");
 			goto stray;
 		}
 		vector = (int)inta;
-	} else if (vector == 15)
+	} else if (vector == 15) {
+		PCPU_INC(md.stats.pcs_nstrays);
 		goto stray;
+	}
 
 	if (vector == CLOCK_VECTOR) {/* clock interrupt */
 		/* CTR0(KTR_INTR, "clock interrupt"); */
 
 		itc = ia64_get_itc();
 
-		PCPU_INC(cnt.v_intr);
+		PCPU_INC(md.stats.pcs_nclks);
 #ifdef EVCNT_COUNTERS
 		clock_intr_evcnt.ev_count++;
 #else
 		intrcnt[INTRCNT_CLOCK]++;
 #endif
-		clks[PCPU_GET(cpuid)]++;
 
 		critical_enter();
 
-		adj = PCPU_GET(clockadj);
-		clk = PCPU_GET(clock);
+		adj = PCPU_GET(md.clockadj);
+		clk = PCPU_GET(md.clock);
 		delta = itc - clk;
 		count = 0;
 		while (delta >= ia64_clock_reload) {
@@ -206,33 +188,36 @@ interrupt(struct trapframe *tf)
 			adj = 0;
 			adjust_excess++;
 		}
-		PCPU_SET(clock, clk);
-		PCPU_SET(clockadj, adj);
+		PCPU_SET(md.clock, clk);
+		PCPU_SET(md.clockadj, adj);
 		critical_exit();
 		ia64_srlz_d();
 
 #ifdef SMP
 	} else if (vector == ipi_vector[IPI_AST]) {
-		asts[PCPU_GET(cpuid)]++;
+		PCPU_INC(md.stats.pcs_nasts);
 		CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
 	} else if (vector == ipi_vector[IPI_HIGH_FP]) {
+		PCPU_INC(md.stats.pcs_nhighfps);
 		ia64_highfp_save_ipi();
 	} else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
-		rdvs[PCPU_GET(cpuid)]++;
+		PCPU_INC(md.stats.pcs_nrdvs);
 		CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
 		enable_intr();
 		smp_rendezvous_action();
 		disable_intr();
 	} else if (vector == ipi_vector[IPI_STOP]) {
+		PCPU_INC(md.stats.pcs_nstops);
 		cpumask_t mybit = PCPU_GET(cpumask);
 
-		savectx(PCPU_PTR(pcb));
+		savectx(PCPU_PTR(md.pcb));
 		atomic_set_int(&stopped_cpus, mybit);
 		while ((started_cpus & mybit) == 0)
 			cpu_spinwait();
 		atomic_clear_int(&started_cpus, mybit);
 		atomic_clear_int(&stopped_cpus, mybit);
 	} else if (vector == ipi_vector[IPI_PREEMPT]) {
+		PCPU_INC(md.stats.pcs_npreempts);
 		CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid));
 		__asm __volatile("mov cr.eoi = r0;; srlz.d");
 		enable_intr();
@@ -241,7 +226,7 @@ interrupt(struct trapframe *tf)
 		goto stray;
 #endif
 	} else {
-		ints[PCPU_GET(cpuid)]++;
+		PCPU_INC(md.stats.pcs_nhwints);
 		atomic_add_int(&td->td_intr_nesting_level, 1);
 		ia64_dispatch_intr(tf, vector);
 		atomic_subtract_int(&td->td_intr_nesting_level, 1);

Modified: stable/8/sys/ia64/ia64/machdep.c
==============================================================================
--- stable/8/sys/ia64/ia64/machdep.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/machdep.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -101,6 +101,8 @@ __FBSDID("$FreeBSD$");
 
 #include <i386/include/specialreg.h>
 
+SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, "");
+
 u_int64_t processor_frequency;
 u_int64_t bus_frequency;
 u_int64_t itc_frequency;
@@ -139,8 +141,6 @@ SYSCTL_STRING(_hw, OID_AUTO, family, CTL
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
-static void cpu_startup(void *);
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
 struct msgbuf *msgbufp = NULL;
 
@@ -247,9 +247,11 @@ identifycpu(void)
 }
 
 static void
-cpu_startup(dummy)
-	void *dummy;
+cpu_startup(void *dummy)
 {
+	char nodename[16];
+	struct pcpu *pc;
+	struct pcpu_stats *pcs;
 
 	/*
 	 * Good {morning,afternoon,evening,night}.
@@ -302,7 +304,68 @@ cpu_startup(dummy)
 	 */
 	ia64_probe_sapics();
 	ia64_mca_init();
+
+	/*
+	 * Create sysctl tree for per-CPU information.
+	 */
+	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
+		snprintf(nodename, sizeof(nodename), "%u", pc->pc_cpuid);
+		sysctl_ctx_init(&pc->pc_md.sysctl_ctx);
+		pc->pc_md.sysctl_tree = SYSCTL_ADD_NODE(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_STATIC_CHILDREN(_machdep_cpu), OID_AUTO, nodename,
+		    CTLFLAG_RD, NULL, "");
+		if (pc->pc_md.sysctl_tree == NULL)
+			continue;
+
+		pcs = &pc->pc_md.stats;
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nasts", CTLFLAG_RD, &pcs->pcs_nasts,
+		    "Number of IPI_AST interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nclks", CTLFLAG_RD, &pcs->pcs_nclks,
+		    "Number of clock interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nextints", CTLFLAG_RD, &pcs->pcs_nextints,
+		    "Number of ExtINT interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nhighfps", CTLFLAG_RD, &pcs->pcs_nhighfps,
+		    "Number of IPI_HIGH_FP interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nhwints", CTLFLAG_RD, &pcs->pcs_nhwints,
+		    "Number of hardware (device) interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "npreempts", CTLFLAG_RD, &pcs->pcs_npreempts,
+		    "Number of IPI_PREEMPT interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nrdvs", CTLFLAG_RD, &pcs->pcs_nrdvs,
+		    "Number of IPI_RENDEZVOUS interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nstops", CTLFLAG_RD, &pcs->pcs_nstops,
+		    "Number of IPI_STOP interrupts");
+
+		SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+		    SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+		    "nstrays", CTLFLAG_RD, &pcs->pcs_nstrays,
+		    "Number of stray vectors");
+	}
 }
+SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
 void
 cpu_boot(int howto)

Modified: stable/8/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- stable/8/sys/ia64/ia64/mp_machdep.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/mp_machdep.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -76,7 +76,6 @@ void ia64_ap_startup(void);
 /* Variables used by os_boot_rendez and ia64_ap_startup */
 struct pcpu *ap_pcpu;
 void *ap_stack;
-uint64_t ap_vhpt;
 volatile int ap_delay;
 volatile int ap_awake;
 volatile int ap_spin;
@@ -116,13 +115,15 @@ void
 ia64_ap_startup(void)
 {
 	volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK;
+	uint64_t vhpt;
 	int vector;
 
 	pcpup = ap_pcpu;
 	ia64_set_k4((intptr_t)pcpup);
 
-	map_vhpt(ap_vhpt);
-	ia64_set_pta(ap_vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
+	vhpt = PCPU_GET(md.vhpt);
+	map_vhpt(vhpt);
+	ia64_set_pta(vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
 	ia64_srlz_i();
 
 	ap_awake = 1;
@@ -225,7 +226,7 @@ cpu_mp_add(u_int acpiid, u_int apicid, u
 		pc = pcpup;
 
 	pc->pc_acpi_id = acpiid;
-	pc->pc_lid = lid;
+	pc->pc_md.lid = lid;
 	all_cpus |= (1UL << cpuid);
 }
 
@@ -239,8 +240,8 @@ cpu_mp_announce()
 		pc = pcpu_find(i);
 		if (pc != NULL) {
 			printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x",
-			    i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_lid),
-			    LID_SAPIC_EID(pc->pc_lid));
+			    i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_md.lid),
+			    LID_SAPIC_EID(pc->pc_md.lid));
 			if (i == 0)
 				printf(" (BSP)\n");
 			else
@@ -257,13 +258,18 @@ cpu_mp_start()
 	ap_spin = 1;
 
 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
-		pc->pc_current_pmap = kernel_pmap;
+		pc->pc_md.current_pmap = kernel_pmap;
 		pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask;
 		if (pc->pc_cpuid > 0) {
 			ap_pcpu = pc;
+			pc->pc_md.vhpt = pmap_alloc_vhpt();
+			if (pc->pc_md.vhpt == 0) {
+				printf("SMP: WARNING: unable to allocate VHPT"
+				    " for cpu%d", pc->pc_cpuid);
+				continue;
+			}
 			ap_stack = malloc(KSTACK_PAGES * PAGE_SIZE, M_SMP,
 			    M_WAITOK);
-			ap_vhpt = pmap_vhpt_base[pc->pc_cpuid];
 			ap_delay = 2000;
 			ap_awake = 0;
 
@@ -275,13 +281,13 @@ cpu_mp_start()
 			do {
 				DELAY(1000);
 			} while (--ap_delay > 0);
-			pc->pc_awake = ap_awake;
+			pc->pc_md.awake = ap_awake;
 
 			if (!ap_awake)
 				printf("SMP: WARNING: cpu%d did not wake up\n",
 				    pc->pc_cpuid);
 		} else
-			pc->pc_awake = 1;
+			pc->pc_md.awake = 1;
 	}
 }
 
@@ -298,7 +304,7 @@ cpu_mp_unleash(void *dummy)
 	smp_cpus = 0;
 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
 		cpus++;
-		if (pc->pc_awake) {
+		if (pc->pc_md.awake) {
 			kproc_create(ia64_store_mca_state,
 			    (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0,
 			    "mca %u", pc->pc_cpuid);
@@ -361,7 +367,7 @@ ipi_send(struct pcpu *cpu, int ipi)
 	uint64_t vector;
 
 	pipi = __MEMIO_ADDR(ia64_lapic_address |
-	    ((cpu->pc_lid & LID_SAPIC_MASK) >> 12));
+	    ((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12));
 	vector = (uint64_t)(ipi_vector[ipi] & 0xff);
 	KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi));
 	*pipi = vector;

Modified: stable/8/sys/ia64/ia64/pmap.c
==============================================================================
--- stable/8/sys/ia64/ia64/pmap.c	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/ia64/pmap.c	Sat Dec 12 05:14:40 2009	(r200431)
@@ -217,8 +217,6 @@ int pmap_vhpt_nbuckets;
 SYSCTL_INT(_machdep_vhpt, OID_AUTO, nbuckets, CTLFLAG_RD,
     &pmap_vhpt_nbuckets, 0, "");
 
-uint64_t pmap_vhpt_base[MAXCPU];
-
 int pmap_vhpt_log2size = 0;
 TUNABLE_INT("machdep.vhpt.log2size", &pmap_vhpt_log2size);
 SYSCTL_INT(_machdep_vhpt, OID_AUTO, log2size, CTLFLAG_RD,
@@ -277,6 +275,40 @@ pmap_steal_memory(vm_size_t size)
 	return va;
 }
 
+static void
+pmap_initialize_vhpt(vm_offset_t vhpt)
+{
+	struct ia64_lpte *pte;
+	u_int i;
+
+	pte = (struct ia64_lpte *)vhpt;
+	for (i = 0; i < pmap_vhpt_nbuckets; i++) {
+		pte[i].pte = 0;
+		pte[i].itir = 0;
+		pte[i].tag = 1UL << 63; /* Invalid tag */
+		pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i);
+	}
+}
+
+#ifdef SMP
+MALLOC_DECLARE(M_SMP);
+
+vm_offset_t
+pmap_alloc_vhpt(void)
+{
+	vm_offset_t vhpt;
+	vm_size_t size;
+
+	size = 1UL << pmap_vhpt_log2size;
+	vhpt = (uintptr_t)contigmalloc(size, M_SMP, 0, 0UL, ~0UL, size, 0UL);
+	if (vhpt != 0) {
+		vhpt = IA64_PHYS_TO_RR7(ia64_tpa(vhpt));
+		pmap_initialize_vhpt(vhpt);
+	}
+	return (vhpt);
+}
+#endif
+
 /*
  *	Bootstrap the system enough to run with virtual memory.
  */
@@ -284,8 +316,7 @@ void
 pmap_bootstrap()
 {
 	struct ia64_pal_result res;
-	struct ia64_lpte *pte;
-	vm_offset_t base, limit;
+	vm_offset_t base;
 	size_t size;
 	int i, j, count, ridbits;
 
@@ -365,94 +396,52 @@ pmap_bootstrap()
 		;
 	count = i+2;
 
-	/*
-	 * Figure out a useful size for the VHPT, based on the size of
-	 * physical memory and try to locate a region which is large
-	 * enough to contain the VHPT (which must be a power of two in
-	 * size and aligned to a natural boundary).
-	 * We silently bump up the VHPT size to the minimum size if the
-	 * user has set the tunable too small. Likewise, the VHPT size
-	 * is silently capped to the maximum allowed.
-	 */
 	TUNABLE_INT_FETCH("machdep.vhpt.log2size", &pmap_vhpt_log2size);
-	if (pmap_vhpt_log2size == 0) {
-		pmap_vhpt_log2size = 15;
-		size = 1UL << pmap_vhpt_log2size;
-		while (size < Maxmem * 32) {
-			pmap_vhpt_log2size++;
-			size <<= 1;
-		}
-	} else if (pmap_vhpt_log2size < 15)
+	if (pmap_vhpt_log2size == 0)
+		pmap_vhpt_log2size = 20;
+	else if (pmap_vhpt_log2size < 15)
 		pmap_vhpt_log2size = 15;
-	if (pmap_vhpt_log2size > 61)
+	else if (pmap_vhpt_log2size > 61)
 		pmap_vhpt_log2size = 61;
 
-	pmap_vhpt_base[0] = 0;
-	base = limit = 0;
+	base = 0;
 	size = 1UL << pmap_vhpt_log2size;
-	while (pmap_vhpt_base[0] == 0) {
-		if (bootverbose)
-			printf("Trying VHPT size 0x%lx\n", size);
-		for (i = 0; i < count; i += 2) {
-			base = (phys_avail[i] + size - 1) & ~(size - 1);
-			limit = base + MAXCPU * size;
-			if (limit <= phys_avail[i+1])
-				/*
-				 * VHPT can fit in this region
-				 */
-				break;
-		}
-		if (!phys_avail[i]) {
-			/* Can't fit, try next smaller size. */
-			pmap_vhpt_log2size--;
-			size >>= 1;
-		} else
-			pmap_vhpt_base[0] = IA64_PHYS_TO_RR7(base);
+	for (i = 0; i < count; i += 2) {
+		base = (phys_avail[i] + size - 1) & ~(size - 1);
+		if (base + size <= phys_avail[i+1])
+			break;
 	}
-	if (pmap_vhpt_log2size < 15)
-		panic("Can't find space for VHPT");
-
-	if (bootverbose)
-		printf("Putting VHPT at 0x%lx\n", base);
+	if (!phys_avail[i])
+		panic("Unable to allocate VHPT");
 
 	if (base != phys_avail[i]) {
 		/* Split this region. */
-		if (bootverbose)
-			printf("Splitting [%p-%p]\n", (void *)phys_avail[i],
-			    (void *)phys_avail[i+1]);
 		for (j = count; j > i; j -= 2) {
 			phys_avail[j] = phys_avail[j-2];
 			phys_avail[j+1] = phys_avail[j-2+1];
 		}
 		phys_avail[i+1] = base;
-		phys_avail[i+2] = limit;
+		phys_avail[i+2] = base + size;
 	} else
-		phys_avail[i] = limit;
+		phys_avail[i] = base + size;
 
-	pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte);
+	base = IA64_PHYS_TO_RR7(base);
+	PCPU_SET(md.vhpt, base);
+	if (bootverbose)
+		printf("VHPT: address=%#lx, size=%#lx\n", base, size);
 
+	pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte);
 	pmap_vhpt_bucket = (void *)pmap_steal_memory(pmap_vhpt_nbuckets *
 	    sizeof(struct ia64_bucket));
-	pte = (struct ia64_lpte *)pmap_vhpt_base[0];
 	for (i = 0; i < pmap_vhpt_nbuckets; i++) {
-		pte[i].pte = 0;
-		pte[i].itir = 0;
-		pte[i].tag = 1UL << 63;	/* Invalid tag */
-		pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i);
-		/* Stolen memory is zeroed! */
+		/* Stolen memory is zeroed. */
 		mtx_init(&pmap_vhpt_bucket[i].mutex, "VHPT bucket lock", NULL,
 		    MTX_NOWITNESS | MTX_SPIN);
 	}
 
-	for (i = 1; i < MAXCPU; i++) {
-		pmap_vhpt_base[i] = pmap_vhpt_base[i - 1] + size;
-		bcopy((void *)pmap_vhpt_base[i - 1], (void *)pmap_vhpt_base[i],
-		    size);
-	}
-
-	map_vhpt(pmap_vhpt_base[0]);
-	ia64_set_pta(pmap_vhpt_base[0] + (1 << 8) +
-	    (pmap_vhpt_log2size << 2) + 1);
+	pmap_initialize_vhpt(base);
+	map_vhpt(base);
+	ia64_set_pta(base + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
 	ia64_srlz_i();
 
 	virtual_avail = VM_MIN_KERNEL_ADDRESS;
@@ -466,7 +455,7 @@ pmap_bootstrap()
 		kernel_pmap->pm_rid[i] = 0;
 	kernel_pmap->pm_active = 1;
 	TAILQ_INIT(&kernel_pmap->pm_pvlist);
-	PCPU_SET(current_pmap, kernel_pmap);
+	PCPU_SET(md.current_pmap, kernel_pmap);
 
 	/*
 	 * Region 5 is mapped via the vhpt.
@@ -551,15 +540,16 @@ static void
 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
 {
 	struct ia64_lpte *pte;
-	int i, vhpt_ofs;
+	struct pcpu *pc;
+	u_int vhpt_ofs;
 
-	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
 		("invalidating TLB for non-current pmap"));
 
-	vhpt_ofs = ia64_thash(va) - pmap_vhpt_base[PCPU_GET(cpuid)];
+	vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt);
 	critical_enter();
-	for (i = 0; i < MAXCPU; i++) {
-		pte = (struct ia64_lpte *)(pmap_vhpt_base[i] + vhpt_ofs);
+	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
+		pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs);
 		if (pte->tag == ia64_ttag(va))
 			pte->tag = 1UL << 63;
 	}
@@ -591,7 +581,7 @@ static void
 pmap_invalidate_all(pmap_t pmap)
 {
 
-	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
 		("invalidating TLB for non-current pmap"));
 
 #ifdef SMP
@@ -1172,7 +1162,7 @@ pmap_remove_pte(pmap_t pmap, struct ia64
 	int error;
 	vm_page_t m;
 
-	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
 		("removing pte for non-current pmap"));
 
 	/*
@@ -1340,7 +1330,7 @@ pmap_remove_page(pmap_t pmap, vm_offset_
 {
 	struct ia64_lpte *pte;
 
-	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
 		("removing page for non-current pmap"));
 
 	pte = pmap_find_vhpt(va);
@@ -2251,7 +2241,7 @@ pmap_switch(pmap_t pm)
 	int i;
 
 	critical_enter();
-	prevpm = PCPU_GET(current_pmap);
+	prevpm = PCPU_GET(md.current_pmap);
 	if (prevpm == pm)
 		goto out;
 	if (prevpm != NULL)
@@ -2268,7 +2258,7 @@ pmap_switch(pmap_t pm)
 		}
 		atomic_set_32(&pm->pm_active, PCPU_GET(cpumask));
 	}
-	PCPU_SET(current_pmap, pm);
+	PCPU_SET(md.current_pmap, pm);
 	ia64_srlz_d();
 
 out:

Modified: stable/8/sys/ia64/include/kdb.h
==============================================================================
--- stable/8/sys/ia64/include/kdb.h	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/include/kdb.h	Sat Dec 12 05:14:40 2009	(r200431)
@@ -33,7 +33,7 @@
 #include <machine/frame.h>
 #include <machine/ia64_cpu.h>
 
-#define	KDB_STOPPEDPCB(pc)	(&(pc)->pc_pcb)
+#define	KDB_STOPPEDPCB(pc)	(&(pc)->pc_md.pcb)
 
 static __inline void
 kdb_cpu_clear_singlestep(void)

Modified: stable/8/sys/ia64/include/param.h
==============================================================================
--- stable/8/sys/ia64/include/param.h	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/include/param.h	Sat Dec 12 05:14:40 2009	(r200431)
@@ -70,7 +70,7 @@
 #endif
 
 #if defined(SMP) || defined(KLD_MODULE)
-#define	MAXCPU		4
+#define	MAXCPU		32
 #else
 #define MAXCPU		1
 #endif

Modified: stable/8/sys/ia64/include/pcpu.h
==============================================================================
--- stable/8/sys/ia64/include/pcpu.h	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/include/pcpu.h	Sat Dec 12 05:14:40 2009	(r200431)
@@ -30,16 +30,39 @@
 #ifndef	_MACHINE_PCPU_H_
 #define	_MACHINE_PCPU_H_
 
+#include <sys/sysctl.h>
 #include <machine/pcb.h>
 
+struct pcpu_stats {
+	u_long		pcs_nasts;		/* IPI_AST counter. */
+	u_long		pcs_nclks;		/* Clock interrupt counter. */
+	u_long		pcs_nextints;		/* ExtINT counter. */
+	u_long		pcs_nhighfps;		/* IPI_HIGH_FP counter. */
+	u_long		pcs_nhwints;		/* Hardware int. counter. */
+	u_long		pcs_npreempts;		/* IPI_PREEMPT counter. */
+	u_long		pcs_nrdvs;		/* IPI_RENDEZVOUS counter. */
+	u_long		pcs_nstops;		/* IPI_STOP counter. */
+	u_long		pcs_nstrays;		/* Stray interrupt counter. */
+};
+
+struct pcpu_md {
+	struct pcb	pcb;			/* Used by IPI_STOP */
+	struct pmap	*current_pmap;		/* active pmap */
+	vm_offset_t	vhpt;			/* Address of VHPT */
+	uint64_t	lid;			/* local CPU ID */
+	uint64_t	clock;			/* Clock counter. */
+	uint64_t	clockadj;		/* Clock adjust. */
+	uint32_t	awake:1;		/* CPU is awake? */
+	struct pcpu_stats stats;		/* Interrupt stats. */
+#ifdef _KERNEL
+	struct sysctl_ctx_list sysctl_ctx;
+	struct sysctl_oid *sysctl_tree;
+#endif
+};
+
 #define	PCPU_MD_FIELDS							\
-	struct pcb	pc_pcb;			/* Used by IPI_STOP */	\
-	struct pmap	*pc_current_pmap;	/* active pmap */	\
-	uint64_t	pc_lid;			/* local CPU ID */	\
-	uint64_t	pc_clock;		/* Clock counter. */	\
-	uint64_t	pc_clockadj;		/* Clock adjust. */	\
-	uint32_t	pc_awake:1;		/* CPU is awake? */	\
-	uint32_t	pc_acpi_id		/* ACPI CPU id. */
+	uint32_t	pc_acpi_id;		/* ACPI CPU id. */	\
+	struct pcpu_md	pc_md			/* MD fields. */
 
 #ifdef _KERNEL
 

Modified: stable/8/sys/ia64/include/pmap.h
==============================================================================
--- stable/8/sys/ia64/include/pmap.h	Sat Dec 12 04:50:04 2009	(r200430)
+++ stable/8/sys/ia64/include/pmap.h	Sat Dec 12 05:14:40 2009	(r200431)
@@ -125,6 +125,7 @@ extern int pmap_vhpt_log2size;
 #define	pmap_unmapbios(va, sz)	pmap_unmapdev(va, sz)
 
 vm_offset_t pmap_steal_memory(vm_size_t);
+vm_offset_t pmap_alloc_vhpt(void);
 void	pmap_bootstrap(void);
 void	pmap_kenter(vm_offset_t va, vm_offset_t pa);
 vm_paddr_t pmap_kextract(vm_offset_t va);


More information about the svn-src-all mailing list