MFC rev 199893, 199941, 200200 and 200207:

o   Eliminate MAXCPU.
o   Revamp the PCPU structure.
This commit is contained in:
Marcel Moolenaar 2009-12-12 05:14:40 +00:00
parent f695ba479e
commit 5b574e433f
10 changed files with 210 additions and 142 deletions

View file

@ -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();
}

View file

@ -91,7 +91,7 @@ ASSYM(MC_SPECIAL_RNAT, offsetof(mcontext_t, mc_special.rnat));
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));

View file

@ -84,28 +84,6 @@ dummy_perf(unsigned long vector, struct trapframe *tf)
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);

View file

@ -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, CTLFLAG_RD, cpu_family, 0,
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)

View file

@ -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_int apiceid)
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;

View file

@ -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) {
if (pmap_vhpt_log2size == 0)
pmap_vhpt_log2size = 20;
else if (pmap_vhpt_log2size < 15)
pmap_vhpt_log2size = 15;
size = 1UL << pmap_vhpt_log2size;
while (size < Maxmem * 32) {
pmap_vhpt_log2size++;
size <<= 1;
}
} 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;
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_lpte *pte, vm_offset_t va,
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_t va)
{
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:

View file

@ -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)

View file

@ -70,7 +70,7 @@
#endif
#if defined(SMP) || defined(KLD_MODULE)
#define MAXCPU 4
#define MAXCPU 32
#else
#define MAXCPU 1
#endif

View file

@ -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

View file

@ -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);