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

[Xen-changelog] Batch p.t. pin requests during guest restore (after being suspended, or



ChangeSet 1.1419, 2005/04/01 11:04:58+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Batch p.t. pin requests during guest restore (after being suspended, or
        after migration). Allow L1 tables to be pinned even after their va
        backptr is fixed (no longer mutable).
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 tools/libxc/xc_linux_restore.c |   39 +++++++++++++++++++--------------------
 tools/libxc/xc_private.c       |   27 +++------------------------
 tools/libxc/xc_private.h       |   32 ++++++++++++++++++++++++++++++++
 xen/arch/x86/mm.c              |    8 ++------
 4 files changed, 56 insertions(+), 50 deletions(-)


diff -Nru a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    2005-04-01 06:03:31 -05:00
+++ b/tools/libxc/xc_linux_restore.c    2005-04-01 06:03:31 -05:00
@@ -106,6 +106,10 @@
     /* used by debug verify code */
     unsigned long buf[PAGE_SIZE/sizeof(unsigned long)];
 
+#define MAX_PIN_BATCH 1024
+    struct mmuext_op pin[MAX_PIN_BATCH];
+    unsigned int nr_pins = 0;
+
     xcio_info(ioctxt, "xc_linux_restore start\n");
 
     if ( mlock(&ctxt, sizeof(ctxt) ) )
@@ -414,38 +418,33 @@
 
     xcio_info(ioctxt, "Received all pages\n");
 
+    if ( finish_mmu_updates(xc_handle, mmu) )
+        goto out;
+
     /*
      * Pin page tables. Do this after writing to them as otherwise Xen
      * will barf when doing the type-checking.
      */
     for ( i = 0; i < nr_pfns; i++ )
     {
+        if ( (pfn_type[i] & LPINTAB) == 0 )
+            continue;
         if ( pfn_type[i] == (L1TAB|LPINTAB) )
+            pin[nr_pins].cmd = MMUEXT_PIN_L1_TABLE;
+        else /* pfn_type[i] == (L2TAB|LPINTAB) */
+            pin[nr_pins].cmd = MMUEXT_PIN_L2_TABLE;
+        pin[nr_pins].mfn = pfn_to_mfn_table[i];
+        if ( ++nr_pins == MAX_PIN_BATCH )
         {
-            if ( pin_table(xc_handle, MMUEXT_PIN_L1_TABLE,
-                           pfn_to_mfn_table[i], dom) ) {
-                printf("ERR pin L1 pfn=%lx mfn=%lx\n",
-                       (unsigned long)i, pfn_to_mfn_table[i]);
-                goto out;
-            }
-        }
-    }
-
-    /* must pin all L1's before L2's (need consistent va back ptr) */
-    for ( i = 0; i < nr_pfns; i++ )
-    {
-        if ( pfn_type[i] == (L2TAB|LPINTAB) )
-        {
-            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
-                           pfn_to_mfn_table[i], dom) ) {
-                printf("ERR pin L2 pfn=%lx mfn=%lx\n",
-                       (unsigned long)i, pfn_to_mfn_table[i]);
+            if ( do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 )
                 goto out;
-            }
+            nr_pins = 0;
         }
     }
 
-    if ( finish_mmu_updates(xc_handle, mmu) ) goto out;
+    if ( (nr_pins != 0) &&
+         (do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
+        goto out;
 
     xcio_info(ioctxt, "\b\b\b\b100%%\n");
     xcio_info(ioctxt, "Memory reloaded.\n");
diff -Nru a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  2005-04-01 06:03:30 -05:00
+++ b/tools/libxc/xc_private.c  2005-04-01 06:03:30 -05:00
@@ -95,36 +95,15 @@
 int pin_table(
     int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
 {
-    int err = 0;
     struct mmuext_op op;
-    privcmd_hypercall_t hypercall;
 
     op.cmd = type;
     op.mfn = mfn;
 
-    hypercall.op     = __HYPERVISOR_mmuext_op;
-    hypercall.arg[0] = (unsigned long)&op;
-    hypercall.arg[1] = 1;
-    hypercall.arg[2] = 0;
-    hypercall.arg[3] = dom;
+    if ( do_mmuext_op(xc_handle, &op, 1, dom) < 0 )
+        return 1;
 
-    if ( mlock(&op, sizeof(op)) != 0 )
-    {
-        PERROR("Could not lock mmuext_op");
-        err = 1;
-        goto out;
-    }
-
-    if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
-    {
-        ERROR("Failure when submitting mmu updates");
-        err = 1;
-    }
-
-    (void)munlock(&op, sizeof(op));
-
- out:
-    return err;
+    return 0;
 }
 
 static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
diff -Nru a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  2005-04-01 06:03:30 -05:00
+++ b/tools/libxc/xc_private.h  2005-04-01 06:03:30 -05:00
@@ -142,6 +142,38 @@
  out1: return ret;
 }    
 
+static inline int do_mmuext_op(
+    int xc_handle,
+    struct mmuext_op *op,
+    unsigned int nr_ops,
+    domid_t dom)
+{
+    privcmd_hypercall_t hypercall;
+    long ret = -EINVAL;
+       
+    hypercall.op     = __HYPERVISOR_mmuext_op;
+    hypercall.arg[0] = (unsigned long)op;
+    hypercall.arg[1] = (unsigned long)nr_ops;
+    hypercall.arg[2] = (unsigned long)0;
+    hypercall.arg[3] = (unsigned long)dom;
+
+    if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
+                    " rebuild the user-space tool set?\n",ret,errno);
+        goto out2;
+    }
+
+ out2: (void)munlock(op, nr_ops*sizeof(*op));
+ out1: return ret;
+}    
+
 
 /*
  * PFN mapping.
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2005-04-01 06:03:30 -05:00
+++ b/xen/arch/x86/mm.c 2005-04-01 06:03:30 -05:00
@@ -1186,7 +1186,8 @@
                 nx &= ~PGT_va_mask;
                 nx |= type; /* we know the actual type is correct */
             }
-            else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) )
+            else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
+                      ((type & PGT_va_mask) != (x & PGT_va_mask)) )
             {
                 /* This table is potentially mapped at multiple locations. */
                 nx &= ~PGT_va_mask;
@@ -1388,11 +1389,6 @@
         switch ( op.cmd )
         {
         case MMUEXT_PIN_L1_TABLE:
-            /*
-             * We insist that, if you pin an L1 page, it's the first thing that
-             * you do to it. This is because we require the backptr to still be
-             * mutable. This assumption seems safe.
-             */
             type = PGT_l1_page_table | PGT_va_mutable;
 
         pin_page:

_______________________________________________
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®.