diff options
Diffstat (limited to 'sys/i386/xen')
-rw-r--r-- | sys/i386/xen/mp_machdep.c | 97 | ||||
-rw-r--r-- | sys/i386/xen/pmap.c | 93 |
2 files changed, 44 insertions, 146 deletions
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 6e0fa23..2cd0762 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -153,7 +153,6 @@ static cpumask_t hyperthreading_cpus_mask; extern void Xhypervisor_callback(void); extern void failsafe_callback(void); -extern void pmap_lazyfix_action(void); struct cpu_group * cpu_topo(void) @@ -340,24 +339,16 @@ iv_invlcache(uintptr_t a, uintptr_t b) atomic_add_int(&smp_tlb_wait, 1); } -static void -iv_lazypmap(uintptr_t a, uintptr_t b) -{ - pmap_lazyfix_action(); - atomic_add_int(&smp_tlb_wait, 1); -} - /* * These start from "IPI offset" APIC_IPI_INTS */ -static call_data_func_t *ipi_vectors[6] = +static call_data_func_t *ipi_vectors[5] = { iv_rendezvous, iv_invltlb, iv_invlpg, iv_invlrng, iv_invlcache, - iv_lazypmap, }; /* @@ -957,6 +948,30 @@ start_ap(int apic_id) } /* + * send an IPI to a specific CPU. + */ +static void +ipi_send_cpu(int cpu, u_int ipi) +{ + u_int bitmap, old_pending, new_pending; + + if (IPI_IS_BITMAPED(ipi)) { + bitmap = 1 << ipi; + ipi = IPI_BITMAP_VECTOR; + do { + old_pending = cpu_ipi_pending[cpu]; + new_pending = old_pending | bitmap; + } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], + old_pending, new_pending)); + if (!old_pending) + ipi_pcpu(cpu, RESCHEDULE_VECTOR); + } else { + KASSERT(call_data != NULL, ("call_data not set")); + ipi_pcpu(cpu, CALL_FUNCTION_VECTOR); + } +} + +/* * Flush the TLB on all other CPU's */ static void @@ -1098,14 +1113,6 @@ void ipi_selected(cpumask_t cpus, u_int ipi) { int cpu; - u_int bitmap = 0; - u_int old_pending; - u_int new_pending; - - if (IPI_IS_BITMAPED(ipi)) { - bitmap = 1 << ipi; - ipi = IPI_BITMAP_VECTOR; - } /* * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit @@ -1115,23 +1122,11 @@ ipi_selected(cpumask_t cpus, u_int ipi) if (ipi == IPI_STOP_HARD) atomic_set_int(&ipi_nmi_pending, cpus); - CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; cpus &= ~(1 << cpu); - - if (bitmap) { - do { - old_pending = cpu_ipi_pending[cpu]; - new_pending = old_pending | bitmap; - } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], - old_pending, new_pending)); - if (!old_pending) - ipi_pcpu(cpu, RESCHEDULE_VECTOR); - } else { - KASSERT(call_data != NULL, ("call_data not set")); - ipi_pcpu(cpu, CALL_FUNCTION_VECTOR); - } + CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi); + ipi_send_cpu(cpu, ipi); } } @@ -1141,14 +1136,6 @@ ipi_selected(cpumask_t cpus, u_int ipi) void ipi_cpu(int cpu, u_int ipi) { - u_int bitmap = 0; - u_int old_pending; - u_int new_pending; - - if (IPI_IS_BITMAPED(ipi)) { - bitmap = 1 << ipi; - ipi = IPI_BITMAP_VECTOR; - } /* * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit @@ -1159,19 +1146,7 @@ ipi_cpu(int cpu, u_int ipi) atomic_set_int(&ipi_nmi_pending, 1 << cpu); CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi); - - if (bitmap) { - do { - old_pending = cpu_ipi_pending[cpu]; - new_pending = old_pending | bitmap; - } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], - old_pending, new_pending)); - if (!old_pending) - ipi_pcpu(cpu, RESCHEDULE_VECTOR); - } else { - KASSERT(call_data != NULL, ("call_data not set")); - ipi_pcpu(cpu, CALL_FUNCTION_VECTOR); - } + ipi_send_cpu(cpu, ipi); } /* @@ -1241,6 +1216,22 @@ cpustop_handler(void) } } +void +md_assert_nopreempt(void) +{ +#ifdef INVARIANTS + struct thread *td; + register_t rflags; + + td = curthread; + rflags = read_rflags(); + + if ((rflags & PSL_I) != 0 && td->td_critnest <= 0) + panic("Preemption still allowed, thread %s\n", + (td->td_pinned <= 0) ? "not pinned" : "pinned"); +#endif +} + /* * This is called once the rest of the system is up and running and we're * ready to let the AP's out of the pen. diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c index eb3c803..cf36f5e 100644 --- a/sys/i386/xen/pmap.c +++ b/sys/i386/xen/pmap.c @@ -1681,98 +1681,6 @@ retry: * Pmap allocation/deallocation routines. ***************************************************/ -#ifdef SMP -/* - * Deal with a SMP shootdown of other users of the pmap that we are - * trying to dispose of. This can be a bit hairy. - */ -static cpumask_t *lazymask; -static u_int lazyptd; -static volatile u_int lazywait; - -void pmap_lazyfix_action(void); - -void -pmap_lazyfix_action(void) -{ - cpumask_t mymask = PCPU_GET(cpumask); - -#ifdef COUNT_IPIS - (*ipi_lazypmap_counts[PCPU_GET(cpuid)])++; -#endif - if (rcr3() == lazyptd) - load_cr3(PCPU_GET(curpcb)->pcb_cr3); - atomic_clear_int(lazymask, mymask); - atomic_store_rel_int(&lazywait, 1); -} - -static void -pmap_lazyfix_self(cpumask_t mymask) -{ - - if (rcr3() == lazyptd) - load_cr3(PCPU_GET(curpcb)->pcb_cr3); - atomic_clear_int(lazymask, mymask); -} - - -static void -pmap_lazyfix(pmap_t pmap) -{ - cpumask_t mymask, mask; - u_int spins; - - while ((mask = pmap->pm_active) != 0) { - spins = 50000000; - mask = mask & -mask; /* Find least significant set bit */ - mtx_lock_spin(&smp_ipi_mtx); -#ifdef PAE - lazyptd = vtophys(pmap->pm_pdpt); -#else - lazyptd = vtophys(pmap->pm_pdir); -#endif - mymask = PCPU_GET(cpumask); - if (mask == mymask) { - lazymask = &pmap->pm_active; - pmap_lazyfix_self(mymask); - } else { - atomic_store_rel_int((u_int *)&lazymask, - (u_int)&pmap->pm_active); - atomic_store_rel_int(&lazywait, 0); - ipi_selected(mask, IPI_LAZYPMAP); - while (lazywait == 0) { - ia32_pause(); - if (--spins == 0) - break; - } - } - mtx_unlock_spin(&smp_ipi_mtx); - if (spins == 0) - printf("pmap_lazyfix: spun for 50000000\n"); - } -} - -#else /* SMP */ - -/* - * Cleaning up on uniprocessor is easy. For various reasons, we're - * unlikely to have to even execute this code, including the fact - * that the cleanup is deferred until the parent does a wait(2), which - * means that another userland process has run. - */ -static void -pmap_lazyfix(pmap_t pmap) -{ - u_int cr3; - - cr3 = vtophys(pmap->pm_pdir); - if (cr3 == rcr3()) { - load_cr3(PCPU_GET(curpcb)->pcb_cr3); - pmap->pm_active &= ~(PCPU_GET(cpumask)); - } -} -#endif /* SMP */ - /* * Release any resources held by the given physical map. * Called when a pmap initialized by pmap_pinit is being released. @@ -1798,7 +1706,6 @@ pmap_release(pmap_t pmap) mtx_lock(&createdelete_lock); #endif - pmap_lazyfix(pmap); mtx_lock_spin(&allpmaps_lock); LIST_REMOVE(pmap, pm_list); mtx_unlock_spin(&allpmaps_lock); |