]> xenbits.xensource.com Git - people/aperard/centos-package-xen.git/commitdiff
Backport qemu-xen b04df88, fix for qdisk persisent grants.
authorGeorge Dunlap <george.dunlap@eu.citrix.com>
Thu, 11 Dec 2014 15:37:24 +0000 (15:37 +0000)
committerGeorge Dunlap <george.dunlap@eu.citrix.com>
Thu, 11 Dec 2014 15:37:24 +0000 (15:37 +0000)
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
SOURCES/qemu-xen-b04df88-fix-persistent-unmap.patch [new file with mode: 0644]
SPECS/xen.spec

diff --git a/SOURCES/qemu-xen-b04df88-fix-persistent-unmap.patch b/SOURCES/qemu-xen-b04df88-fix-persistent-unmap.patch
new file mode 100644 (file)
index 0000000..3f326aa
--- /dev/null
@@ -0,0 +1,168 @@
+commit b04df88d41f64fc6b56d193b6e90fb840cedb1d3
+Author: Roger Pau Monne <roger.pau@citrix.com>
+Commit: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+
+    xen_disk: fix unmapping of persistent grants
+    
+    This patch fixes two issues with persistent grants and the disk PV backend
+    (Qdisk):
+    
+     - Keep track of memory regions where persistent grants have been mapped
+       since we need to unmap them as a whole. It is not possible to unmap a
+       single grant if it has been batch-mapped. A new check has also been added
+       to make sure persistent grants are only used if the whole mapped region
+       can be persistently mapped in the batch_maps case.
+     - Unmap persistent grants before switching to the closed state, so the
+       frontend can also free them.
+    
+    upstream-commit-id: 2f01dfacb56bc7a0d4639adc9dff9aae131e6216
+    
+    Signed-off-by: Roger Pau MonnĂ© <roger.pau@citrix.com>
+    Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+    Release-Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+    Reported-by: George Dunlap <george.dunlap@eu.citrix.com>
+    Cc: Kevin Wolf <kwolf@redhat.com>
+    Cc: Stefan Hajnoczi <stefanha@redhat.com>
+    Cc: George Dunlap <george.dunlap@eu.citrix.com>
+    Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
+index 03e30d7..7abecb7 100644
+--- a/hw/block/xen_disk.c
++++ b/hw/block/xen_disk.c
+@@ -58,6 +58,13 @@ struct PersistentGrant {
+ typedef struct PersistentGrant PersistentGrant;
++struct PersistentRegion {
++    void *addr;
++    int num;
++};
++
++typedef struct PersistentRegion PersistentRegion;
++
+ struct ioreq {
+     blkif_request_t     req;
+     int16_t             status;
+@@ -116,6 +123,7 @@ struct XenBlkDev {
+     /* Persistent grants extension */
+     gboolean            feature_persistent;
+     GTree               *persistent_gnts;
++    GSList              *persistent_regions;
+     unsigned int        persistent_gnt_count;
+     unsigned int        max_grants;
+@@ -175,6 +183,23 @@ static void destroy_grant(gpointer pgnt)
+     g_free(grant);
+ }
++static void remove_persistent_region(gpointer data, gpointer dev)
++{
++    PersistentRegion *region = data;
++    struct XenBlkDev *blkdev = dev;
++    XenGnttab gnt = blkdev->xendev.gnttabdev;
++
++    if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) {
++        xen_be_printf(&blkdev->xendev, 0,
++                      "xc_gnttab_munmap region %p failed: %s\n",
++                      region->addr, strerror(errno));
++    }
++    xen_be_printf(&blkdev->xendev, 3,
++                  "unmapped grant region %p with %d pages\n",
++                  region->addr, region->num);
++    g_free(region);
++}
++
+ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
+ {
+     struct ioreq *ioreq = NULL;
+@@ -339,6 +364,7 @@ static int ioreq_map(struct ioreq *ioreq)
+     void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+     int i, j, new_maps = 0;
+     PersistentGrant *grant;
++    PersistentRegion *region;
+     /* domids and refs variables will contain the information necessary
+      * to map the grants that are needed to fulfill this request.
+      *
+@@ -417,7 +443,22 @@ static int ioreq_map(struct ioreq *ioreq)
+             }
+         }
+     }
+-    if (ioreq->blkdev->feature_persistent) {
++    if (ioreq->blkdev->feature_persistent && new_maps != 0 &&
++        (!batch_maps || (ioreq->blkdev->persistent_gnt_count + new_maps <=
++        ioreq->blkdev->max_grants))) {
++        /*
++         * If we are using persistent grants and batch mappings only
++         * add the new maps to the list of persistent grants if the whole
++         * area can be persistently mapped.
++         */
++        if (batch_maps) {
++            region = g_malloc0(sizeof(*region));
++            region->addr = ioreq->pages;
++            region->num = new_maps;
++            ioreq->blkdev->persistent_regions = g_slist_append(
++                                            ioreq->blkdev->persistent_regions,
++                                            region);
++        }
+         while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants)
+               && new_maps) {
+             /* Go through the list of newly mapped grants and add as many
+@@ -443,6 +484,7 @@ static int ioreq_map(struct ioreq *ioreq)
+                           grant);
+             ioreq->blkdev->persistent_gnt_count++;
+         }
++        assert(!batch_maps || new_maps == 0);
+     }
+     for (i = 0; i < ioreq->v.niov; i++) {
+         ioreq->v.iov[i].iov_base += (uintptr_t)page[i];
+@@ -905,7 +947,10 @@ static int blk_connect(struct XenDevice *xendev)
+         blkdev->max_grants = max_requests * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+         blkdev->persistent_gnts = g_tree_new_full((GCompareDataFunc)int_cmp,
+                                              NULL, NULL,
++                                             batch_maps ?
++                                             (GDestroyNotify)g_free :
+                                              (GDestroyNotify)destroy_grant);
++        blkdev->persistent_regions = NULL;
+         blkdev->persistent_gnt_count = 0;
+     }
+@@ -938,6 +983,26 @@ static void blk_disconnect(struct XenDevice *xendev)
+         blkdev->cnt_map--;
+         blkdev->sring = NULL;
+     }
++
++    /*
++     * Unmap persistent grants before switching to the closed state
++     * so the frontend can free them.
++     *
++     * In the !batch_maps case g_tree_destroy will take care of unmapping
++     * the grant, but in the batch_maps case we need to iterate over every
++     * region in persistent_regions and unmap it.
++     */
++    if (blkdev->feature_persistent) {
++        g_tree_destroy(blkdev->persistent_gnts);
++        assert(batch_maps || blkdev->persistent_gnt_count == 0);
++        if (batch_maps) {
++            blkdev->persistent_gnt_count = 0;
++            g_slist_foreach(blkdev->persistent_regions,
++                            (GFunc)remove_persistent_region, blkdev);
++            g_slist_free(blkdev->persistent_regions);
++        }
++        blkdev->feature_persistent = false;
++    }
+ }
+ static int blk_free(struct XenDevice *xendev)
+@@ -949,11 +1014,6 @@ static int blk_free(struct XenDevice *xendev)
+         blk_disconnect(xendev);
+     }
+-    /* Free persistent grants */
+-    if (blkdev->feature_persistent) {
+-        g_tree_destroy(blkdev->persistent_gnts);
+-    }
+-
+     while (!QLIST_EMPTY(&blkdev->freelist)) {
+         ioreq = QLIST_FIRST(&blkdev->freelist);
+         QLIST_REMOVE(ioreq, list);
index cd95101be3d52f2b644c9ed10f15da20ac36ec9c..5bc8ce49dff60a692d3f8f758a933112aef26aeb 100644 (file)
@@ -19,7 +19,7 @@
 Summary: Xen is a virtual machine monitor
 Name:    xen
 Version: 4.4.1
-Release: 2%{?dist}
+Release: 3%{?dist}
 Group:   Development/Libraries
 License: GPLv2+ and LGPLv2+ and BSD
 URL:     http://xen.org/
@@ -62,6 +62,8 @@ Patch1: xen-queue.am
 Patch1001: xen-centos-disableWerror-blktap25.patch
 Patch1005: xen-centos-blktap25-ctl-ipc-restart.patch
 
+Patch2001: qemu-xen-b04df88-fix-persistent-unmap.patch
+
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: transfig libidn-devel zlib-devel texi2html SDL-devel curl-devel
 BuildRequires: libX11-devel python-devel ghostscript texlive-latex
@@ -235,6 +237,9 @@ popd
 %patch1001 -p1
 %patch1005 -p1
 
+pushd tools/qemu-xen
+%patch2001 -p1
+pushd
 
 # stubdom sources
 cp -v %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14} %{SOURCE15} stubdom
@@ -761,6 +766,9 @@ rm -rf %{buildroot}
 %endif
 
 %changelog
+* Thu Dec 11 2014 George Dunlap <george.dunlap@eu.citrix.com> - 4.4.1-3.el6.centos
+ - Backported qdisk persistent grant fix
+
 * Wed Oct 22 2014 George Dunlap <george.dunlap@eu.citrix.com> - 4.4.1-2.el6.centos
  - Updated to blktap 2.5 v0.9.2