Module Name: src Committed By: cherry Date: Sun Dec 4 04:28:41 UTC 2011
Modified Files: src/sys/arch/x86/x86: pmap_tlb.c Log Message: Split out the cross-CPU tlb flushing code between XEN and non-XEN. x86 tlb flushing is asynchronous and uses x86_ipi() XEN tlb flushing uses synchronous hypercalls. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x86/x86/pmap_tlb.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/arch/x86/x86/pmap_tlb.c diff -u src/sys/arch/x86/x86/pmap_tlb.c:1.3 src/sys/arch/x86/x86/pmap_tlb.c:1.4 --- src/sys/arch/x86/x86/pmap_tlb.c:1.3 Wed Jun 15 20:50:02 2011 +++ src/sys/arch/x86/x86/pmap_tlb.c Sun Dec 4 04:28:41 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap_tlb.c,v 1.3 2011/06/15 20:50:02 rmind Exp $ */ +/* $NetBSD: pmap_tlb.c,v 1.4 2011/12/04 04:28:41 cherry Exp $ */ /*- * Copyright (c) 2008-2011 The NetBSD Foundation, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.3 2011/06/15 20:50:02 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.4 2011/12/04 04:28:41 cherry Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -52,7 +52,9 @@ __KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v #include <uvm/uvm.h> #include <machine/cpuvar.h> -#include <x86/pmap.h> +#ifdef XEN +#include <xen/xenpmap.h> +#endif /* XEN */ #include <x86/i82489reg.h> #include <x86/i82489var.h> @@ -261,6 +263,64 @@ pmap_tlb_shootdown(struct pmap *pm, vadd splx(s); } +#ifdef MULTIPROCESSOR +#ifdef XEN +static inline +void pmap_tlb_processpacket(pmap_tlb_packet_t *tp) +{ + struct cpu_info *self = curcpu(); + if (tp->tp_count == (uint16_t)-1) { + xen_mcast_tlbflush(tp->tp_cpumask & + cpus_running & + ~self->ci_cpumask); + } else { + /* Invalidating a single page or a range of pages. */ + int i; + for (i = tp->tp_count - 1; i >= 0; i--) { + xen_mcast_invlpg(tp->tp_va[i], + tp->tp_cpumask & + cpus_running & + ~self->ci_cpumask); + } + } + + /* Ack the request */ + atomic_and_32(&pmap_tlb_mailbox.tm_pending, ~tp->tp_cpumask); +} +#else /* XEN */ +static inline +void pmap_tlb_processpacket(pmap_tlb_packet_t *tp) +{ + int err = 0; + CPU_INFO_ITERATOR cii; + struct cpu_info *lci; + + if (tp->tp_cpumask == cpus_running) { + err = x86_ipi(LAPIC_TLB_VECTOR, LAPIC_DEST_ALLEXCL, + LAPIC_DLMODE_FIXED); + } else { + struct cpu_info *self = curcpu(); + for (CPU_INFO_FOREACH(cii, lci)) { + if (__predict_false(lci == self)) { + continue; + } + if ((lci->ci_cpumask & pmap_tlb_mailbox.tm_pending) == 0) { + continue; + } + KASSERT(lci->ci_flags & CPUF_RUNNING); + + err |= x86_ipi(LAPIC_TLB_VECTOR, + lci->ci_cpuid, LAPIC_DLMODE_FIXED); + } + } + + if (__predict_false(err != 0)) { + panic("pmap_tlb_shootdown: IPI failed"); + } +} +#endif /* XEN */ +#endif /* MULTIPROCESSOR */ + /* * pmap_tlb_shootnow: process pending TLB shootdowns queued on current CPU. * @@ -297,9 +357,7 @@ pmap_tlb_shootnow(void) #ifdef MULTIPROCESSOR if (remote != 0) { - CPU_INFO_ITERATOR cii; - struct cpu_info *lci; - int count, err; + int count; /* * Gain ownership of the shootdown mailbox. We must stay * at IPL_VM once we own it or could deadlock against an @@ -330,29 +388,19 @@ pmap_tlb_shootnow(void) /* * Initiate shootdowns on remote CPUs. */ - if (tp->tp_cpumask == cpus_running) { - err = x86_ipi(LAPIC_TLB_VECTOR, LAPIC_DEST_ALLEXCL, - LAPIC_DLMODE_FIXED); - } else { - err = 0; - for (CPU_INFO_FOREACH(cii, lci)) { - if ((lci->ci_cpumask & remote) == 0) { - continue; - } - if ((lci->ci_flags & CPUF_RUNNING) == 0) { - remote &= ~lci->ci_cpumask; - atomic_and_32(&tm->tm_pending, remote); - continue; - } - err |= x86_ipi(LAPIC_TLB_VECTOR, - lci->ci_cpuid, LAPIC_DLMODE_FIXED); - } - } - if (__predict_false(err != 0)) { - panic("pmap_tlb_shootdown: IPI failed"); - } + /* Trim mailbox wait to only for CPUF_RUNNING cpus */ + atomic_and_32(&tm->tm_pending, cpus_running); + + pmap_tlb_processpacket(tp); +#ifdef XEN + /* + * remote CPUs have been synchronously flushed + */ + remote = 0; +#endif /* XEN */ } -#endif +#endif /* MULTIPROCESSOR */ + /* * Shootdowns on remote CPUs are now in flight. In the meantime, * perform local shootdowns and do not forget to update emap gen.