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

[Xen-devel] [PATCH] tools/libxc: send page-in requests in batches in linux_privcmd_map_foreign_bulk


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Mon, 26 Mar 2012 15:22:36 +0200
  • Delivery-date: Mon, 26 Mar 2012 13:23:06 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1332768138 -7200
# Node ID b66a4a57cee2de421fb5938db04797b5de10162d
# Parent  4bd752a4cdf323c41c50f8cd6286f566d67adeae
tools/libxc: send page-in requests in batches in linux_privcmd_map_foreign_bulk

One of the bottlenecks with foreign page-in request is the poor retry
handling in linux_privcmd_map_foreign_bulk(). It sends one request per
paged gfn at a time and it waits until the gfn is accessible. This
causes long delays in mmap requests from qemu-dm and xc_save.

Instead of sending one request at a time, walk the entire gfn list and
send batches of mmap requests. They will eventually end up in the pagers
request ring (if it has room again), and will fill up this ring so that
in turn the pager can also process page-in in batches.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>

diff -r 4bd752a4cdf3 -r b66a4a57cee2 tools/libxc/xc_linux_osdep.c
--- a/tools/libxc/xc_linux_osdep.c
+++ b/tools/libxc/xc_linux_osdep.c
@@ -191,6 +191,59 @@ static void *linux_privcmd_map_foreign_b
     return addr;
 }
 
+/*
+ * Retry mmap of all paged gfns in batches
+ * retuns < 0 on fatal error
+ * returns 0 if all gfns left paging state
+ * returns > 0 if some gfns are still in paging state
+ *
+ * Walk all gfns and try to assemble blocks of gfns in paging state.
+ * This will keep the request ring full and avoids delays.
+ */
+static int retry_paged(int fd, uint32_t dom, void *addr,
+                       const xen_pfn_t *arr, int *err, unsigned int num)
+{
+    privcmd_mmapbatch_v2_t ioctlx;
+    int rc, paged = 0, i = 0;
+    
+    do
+    {
+        /* Skip gfns not in paging state */
+        if ( err[i] != -ENOENT )
+        {
+            i++;
+            continue;
+        }
+
+        paged++;
+
+        /* At least one gfn is still in paging state */
+        ioctlx.num = 1;
+        ioctlx.dom = dom;
+        ioctlx.addr = (unsigned long)addr + ((unsigned long)i<<XC_PAGE_SHIFT);
+        ioctlx.arr = arr + i;
+        ioctlx.err = err + i;
+        
+        /* Assemble a batch of requests */
+        while ( ++i < num )
+        {
+            if ( err[i] != -ENOENT )
+                break;
+            ioctlx.num++;
+        }
+        
+        /* Send request and abort on fatal error */
+        rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
+        if ( rc < 0 && errno != ENOENT )
+            goto out;
+
+    } while ( i < num );
+    
+    rc = paged;
+out:
+    return rc;
+}
+
 static void *linux_privcmd_map_foreign_bulk(xc_interface *xch, xc_osdep_handle 
h,
                                             uint32_t dom, int prot,
                                             const xen_pfn_t *arr, int *err, 
unsigned int num)
@@ -220,21 +273,10 @@ static void *linux_privcmd_map_foreign_b
     /* Command was recognized, some gfn in arr are in paging state */
     if ( rc < 0 && errno == ENOENT )
     {
-        for ( i = rc = 0; rc == 0 && i < num; i++ )
-        {
-            if ( err[i] != -ENOENT )
-                continue;
-
-            ioctlx.num = 1;
-            ioctlx.dom = dom;
-            ioctlx.addr = (unsigned long)addr + ((unsigned 
long)i<<XC_PAGE_SHIFT);
-            ioctlx.arr = arr + i;
-            ioctlx.err = err + i;
-            do {
-                usleep(100);
-                rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
-            } while ( rc < 0 && errno == ENOENT && err[i] == -ENOENT );
-        }
+        do {
+            usleep(100);
+            rc = retry_paged(fd, dom, addr, arr, err, num);
+        } while ( rc > 0 );
     }
     /* Command was not recognized, use fall back */
     else if ( rc < 0 && errno == EINVAL && (int)num > 0 )

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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