[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Fix multi-VCPU TLB shootdown interface -- specify pointer to VCPU



ChangeSet 1.1420, 2005/04/01 14:17:52+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix multi-VCPU TLB shootdown interface -- specify pointer to VCPU
        bitmap, so it is read at time of flush and not before (which might be
        too early, before all updates are flushed, leading to races). Also
        add selective multi-VCPU shootdown capability to update_va_mapping()
        and use this to make ptep_set_access_flags() a single hypercall.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c     |    2 
 freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c |    2 
 linux-2.4.29-xen-sparse/mm/memory.c                        |    2 
 linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c      |    4 
 linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c      |    2 
 linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c      |    4 
 linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c    |    2 
 linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c      |    2 
 linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h |    3 
 netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c         |    6 
 xen/arch/x86/mm.c                                          |   88 +++++++++----
 xen/include/public/xen.h                                   |   20 +-
 12 files changed, 87 insertions(+), 50 deletions(-)


diff -Nru a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c 
b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c
--- a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c    2005-04-01 
09:02:50 -05:00
+++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c    2005-04-01 
09:02:50 -05:00
@@ -540,7 +540,7 @@
     MCL_QUEUE[MCL_IDX].op = __HYPERVISOR_update_va_mapping;
     MCL_QUEUE[MCL_IDX].args[0] = (unsigned long)va;
     MCL_QUEUE[MCL_IDX].args[1] = (unsigned long)ma;
-    MCL_QUEUE[MCL_IDX].args[2] = UVMF_INVLPG_LOCAL;
+    MCL_QUEUE[MCL_IDX].args[2] = UVMF_INVLPG|UVMF_LOCAL;
     mcl_increment_idx();
 }
 
diff -Nru a/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c 
b/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c
--- a/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c        
2005-04-01 09:02:50 -05:00
+++ b/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c        
2005-04-01 09:02:50 -05:00
@@ -440,7 +440,7 @@
     PT_UPDATES_FLUSH();
 
     /* After all PTEs have been zapped we blow away stale TLB entries. */
-    xn_rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH_LOCAL;
+    xn_rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH|UVMF_LOCAL;
 
     /* Give away a batch of pages. */
     xn_rx_mcl[i].op = __HYPERVISOR_dom_mem_op;
diff -Nru a/linux-2.4.29-xen-sparse/mm/memory.c 
b/linux-2.4.29-xen-sparse/mm/memory.c
--- a/linux-2.4.29-xen-sparse/mm/memory.c       2005-04-01 09:02:50 -05:00
+++ b/linux-2.4.29-xen-sparse/mm/memory.c       2005-04-01 09:02:50 -05:00
@@ -911,7 +911,7 @@
 {
 #ifdef CONFIG_XEN
        if ( likely(vma->vm_mm == current->mm) ) {
-               HYPERVISOR_update_va_mapping(address, entry, UVMF_INVLPG_LOCAL);
+               HYPERVISOR_update_va_mapping(address, entry, 
UVMF_INVLPG|UVMF_LOCAL);
        } else {
                set_pte(page_table, entry);
                flush_tlb_page(vma, address);
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c     2005-04-01 
09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c     2005-04-01 
09:02:50 -05:00
@@ -108,7 +108,7 @@
 {
     struct mmuext_op op;
     op.cmd = MMUEXT_TLB_FLUSH_MULTI;
-    op.cpuset = mask.bits[0];
+    op.cpuset = (unsigned long)mask.bits;
     BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
 }
 
@@ -124,7 +124,7 @@
 {
     struct mmuext_op op;
     op.cmd = MMUEXT_INVLPG_MULTI;
-    op.cpuset = mask.bits[0];
+    op.cpuset = (unsigned long)mask.bits;
     op.linear_addr = ptr & PAGE_MASK;
     BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
 }
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c     2005-04-01 
09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c     2005-04-01 
09:02:50 -05:00
@@ -111,7 +111,7 @@
         mcl[i].args[2] = 0;
     }
 
-    mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH_ALL;
+    mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
     if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
         BUG();
 }
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c     2005-04-01 
09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c     2005-04-01 
09:02:50 -05:00
@@ -270,7 +270,7 @@
     mcl->args[3] = DOMID_SELF;
     mcl++;
 
-    mcl[-3].args[2] = UVMF_TLB_FLUSH_ALL;
+    mcl[-3].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
     if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) )
         BUG();
 
@@ -429,7 +429,7 @@
         mcl++;     
     }
 
-    mcl[-1].args[2] = UVMF_TLB_FLUSH_ALL;
+    mcl[-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
     if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
         BUG();
 
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-04-01 
09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-04-01 
09:02:50 -05:00
@@ -388,7 +388,7 @@
     }
 
     /* After all PTEs have been zapped we blow away stale TLB entries. */
-    rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH_ALL;
+    rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
 
     /* Give away a batch of pages. */
     rx_mcl[i].op = __HYPERVISOR_dom_mem_op;
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c     2005-04-01 
09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c     2005-04-01 
09:02:50 -05:00
@@ -195,7 +195,7 @@
         mcl[i].args[2] = 0;
     }
 
-    mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH_ALL;
+    mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
     if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
         BUG();
 }
diff -Nru a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h 
b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h        
2005-04-01 09:02:50 -05:00
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h        
2005-04-01 09:02:50 -05:00
@@ -407,8 +407,7 @@
        do {                                                              \
                if (__dirty) {                                            \
                        if ( likely((__vma)->vm_mm == current->mm) ) {    \
-                           HYPERVISOR_update_va_mapping((__address), 
(__entry), 0); \
-                           flush_tlb_page((__vma), (__address));         \
+                           HYPERVISOR_update_va_mapping((__address), 
(__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned 
long)((__vma)->vm_mm->cpu_vm_mask.bits)); \
                        } else {                                          \
                             xen_l1_entry_update((__ptep), (__entry).pte_low); \
                            flush_tlb_page((__vma), (__address));         \
diff -Nru a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c 
b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c        2005-04-01 
09:02:50 -05:00
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c        2005-04-01 
09:02:50 -05:00
@@ -598,7 +598,7 @@
        xpq_flush_queue();
 
        /* After all PTEs have been zapped we blow away stale TLB entries. */
-       rx_mcl[nr_pfns-1].args[2] = UVMF_TLB_FLUSH_LOCAL;
+       rx_mcl[nr_pfns-1].args[2] = UVMF_TLB_FLUSH|UVMF_LOCAL;
 
        /* Give away a batch of pages. */
        rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op;
@@ -681,7 +681,7 @@
                mcl->op = __HYPERVISOR_update_va_mapping;
                mcl->args[0] = sc->sc_rx_bufa[rx->id].xb_rx.xbrx_va;
                mcl->args[1] = (rx->addr & PG_FRAME) | PG_V|PG_KW;
-               mcl->args[2] = UVMF_TLB_FLUSH_LOCAL; // 0;
+               mcl->args[2] = UVMF_TLB_FLUSH|UVMF_LOCAL; // 0;
                mcl++;
 
                xpmap_phys_to_machine_mapping
@@ -898,7 +898,7 @@
        xpq_flush_queue();
 
        /* After all PTEs have been zapped we blow away stale TLB entries. */
-       rx_mcl[nr_pfns-1].args[2] = UVMF_TLB_FLUSH_LOCAL;
+       rx_mcl[nr_pfns-1].args[2] = UVMF_TLB_FLUSH|UVMF_LOCAL;
 
        /* Give away a batch of pages. */
        rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op;
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2005-04-01 09:02:50 -05:00
+++ b/xen/arch/x86/mm.c 2005-04-01 09:02:50 -05:00
@@ -1329,6 +1329,25 @@
     return okay;
 }
 
+static inline unsigned long vcpuset_to_pcpuset(
+    struct domain *d, unsigned long vset)
+{
+    unsigned int  vcpu;
+    unsigned long pset = 0;
+    struct exec_domain *ed;
+
+    while ( vset != 0 )
+    {
+        vcpu = find_first_set_bit(vset);
+        vset &= ~(1UL << vcpu);
+        if ( (vcpu < MAX_VIRT_CPUS) &&
+             ((ed = d->exec_domain[vcpu]) != NULL) )
+            pset |= 1UL << ed->processor;
+    }
+
+    return pset;
+}
+
 int do_mmuext_op(
     struct mmuext_op *uops,
     unsigned int count,
@@ -1478,19 +1497,17 @@
         case MMUEXT_TLB_FLUSH_MULTI:
         case MMUEXT_INVLPG_MULTI:
         {
-            unsigned long inset = op.cpuset, outset = 0;
-            while ( inset != 0 )
+            unsigned long vset, pset;
+            if ( unlikely(get_user(vset, (unsigned long *)op.cpuset)) )
             {
-                unsigned int vcpu = find_first_set_bit(inset);
-                inset &= ~(1UL<<vcpu);
-                if ( (vcpu < MAX_VIRT_CPUS) &&
-                     ((ed = d->exec_domain[vcpu]) != NULL) )
-                    outset |= 1UL << ed->processor;
+                okay = 0;
+                break;
             }
+            pset = vcpuset_to_pcpuset(d, vset);
             if ( op.cmd == MMUEXT_TLB_FLUSH_MULTI )
-                flush_tlb_mask(outset & d->cpuset);
+                flush_tlb_mask(pset & d->cpuset);
             else
-                flush_tlb_one_mask(outset & d->cpuset, op.linear_addr);
+                flush_tlb_one_mask(pset & d->cpuset, op.linear_addr);
             break;
         }
 
@@ -1999,6 +2016,7 @@
     struct exec_domain *ed  = current;
     struct domain      *d   = ed->domain;
     unsigned int        cpu = ed->processor;
+    unsigned long       vset, pset, bmap_ptr;
     int                 rc = 0;
 
     perfc_incrc(calls_to_update_va);
@@ -2013,11 +2031,6 @@
 
     cleanup_writable_pagetable(d);
 
-    /*
-     * XXX When we make this support 4MB superpages we should also deal with 
-     * the case of updating L2 entries.
-     */
-
     if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
                                 mk_l1_pgentry(val))) )
         rc = -EINVAL;
@@ -2025,21 +2038,42 @@
     if ( unlikely(shadow_mode_enabled(d)) )
         update_shadow_va_mapping(va, val, ed, d);
 
-    switch ( flags & UVMF_FLUSH_MASK )
+    switch ( flags & UVMF_FLUSHTYPE_MASK )
     {
-    case UVMF_TLB_FLUSH_LOCAL:
-        local_flush_tlb();
-        percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB;
-        break;
-    case UVMF_TLB_FLUSH_ALL:
-        flush_tlb_mask(d->cpuset);
-        percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB;
-        break;
-    case UVMF_INVLPG_LOCAL:
-        local_flush_tlb_one(va);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.