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

[Xen-changelog] [linux-2.6.18-xen] Changes to various backends to handle GNTST_eagain errors.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031870 0
# Node ID 65a7b6de919118c86b3798402901324d4b491249
# Parent  399c485098f6fba099142fed73837d4d6efa7981
Changes to various backends to handle GNTST_eagain errors.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 drivers/xen/blktap/blktap.c                |    4 +++
 drivers/xen/blktap/interface.c             |    8 +++++--
 drivers/xen/blktap2/device.c               |    4 +++
 drivers/xen/gntdev/gntdev.c                |   29 +++++++++++++++++---------
 drivers/xen/scsiback/interface.c           |    8 +++++--
 drivers/xen/scsiback/scsiback.c            |   11 +++++++++
 drivers/xen/sfc_netback/accel_xenbus.c     |    1 
 drivers/xen/sfc_netutil/accel_util.c       |   32 ++++++++++++++++++++++++-----
 drivers/xen/tpmback/interface.c            |    8 +++++--
 drivers/xen/tpmback/tpmback.c              |   21 +++++++++++--------
 drivers/xen/usbback/interface.c            |   16 ++++++++++----
 drivers/xen/usbback/usbback.c              |   10 +++++++++
 drivers/xen/xenbus/xenbus_backend_client.c |   15 +++++++++----
 13 files changed, 130 insertions(+), 37 deletions(-)

diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/blktap/blktap.c       Thu Dec 17 06:37:50 2009 +0000
@@ -1507,6 +1507,8 @@ static void dispatch_rw_block_io(blkif_t
                        if (unlikely(map[i].status != 0)) {
                                WPRINTK("invalid kernel buffer -- "
                                        "could not remap it\n");
+                if(map[i].status == GNTST_eagain)
+                    WPRINTK("grant GNTST_eagain: please use blktap2\n");
                                ret |= 1;
                                map[i].handle = INVALID_GRANT_HANDLE;
                        }
@@ -1544,6 +1546,8 @@ static void dispatch_rw_block_io(blkif_t
                        if (unlikely(map[i].status != 0)) {
                                WPRINTK("invalid kernel buffer -- "
                                        "could not remap it\n");
+                if(map[i].status == GNTST_eagain)
+                    WPRINTK("grant GNTST_eagain: please use blktap2\n");
                                ret |= 1;
                                map[i].handle = INVALID_GRANT_HANDLE;
                        }
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/blktap/interface.c
--- a/drivers/xen/blktap/interface.c    Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/blktap/interface.c    Thu Dec 17 06:37:50 2009 +0000
@@ -33,6 +33,7 @@
 
 #include "common.h"
 #include <xen/evtchn.h>
+#include <linux/delay.h>
 
 static kmem_cache_t *blkif_cachep;
 
@@ -62,8 +63,11 @@ static int map_frontend_page(blkif_t *bl
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while(op.status == GNTST_eagain);
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/blktap2/device.c
--- a/drivers/xen/blktap2/device.c      Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/blktap2/device.c      Thu Dec 17 06:37:50 2009 +0000
@@ -508,6 +508,8 @@ blktap_map_foreign(struct blktap *tap,
 
                if (unlikely(table->grants[grant].status)) {
                        BTERR("invalid kernel buffer: could not remap it\n");
+            /* This should never happen: blkback should handle eagain first */
+            BUG_ON(table->grants[grant].status == GNTST_eagain);
                        err |= 1;
                        table->grants[grant].handle = INVALID_GRANT_HANDLE;
                }
@@ -604,6 +606,8 @@ blktap_map(struct blktap *tap,
                err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
                                                &map, 1);
                BUG_ON(err);
+        /* We are not expecting the grant op to fail */
+        BUG_ON(map.status != GNTST_okay);
 
                err = vm_insert_page(ring->vma, uvaddr, tap_page);
                if (err) {
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/gntdev/gntdev.c
--- a/drivers/xen/gntdev/gntdev.c       Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/gntdev/gntdev.c       Thu Dec 17 06:37:50 2009 +0000
@@ -501,7 +501,7 @@ static int gntdev_mmap (struct file *fli
        unsigned long kernel_vaddr, user_vaddr;
        uint32_t size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        uint64_t ptep;
-       int ret;
+       int ret, exit_ret;
        int flags;
        int i;
        struct page *page;
@@ -578,6 +578,7 @@ static int gntdev_mmap (struct file *fli
        vma->vm_mm->context.has_foreign_mappings = 1;
 #endif
 
+    exit_ret = -ENOMEM;
        for (i = 0; i < size; ++i) {
 
                flags = GNTMAP_host_map;
@@ -599,13 +600,17 @@ static int gntdev_mmap (struct file *fli
                                                &op, 1);
                BUG_ON(ret);
                if (op.status) {
-                       printk(KERN_ERR "Error mapping the grant reference "
-                              "into the kernel (%d). domid = %d; ref = %d\n",
-                              op.status,
-                              private_data->grants[slot_index+i]
-                              .u.valid.domid,
-                              private_data->grants[slot_index+i]
-                              .u.valid.ref);
+            if(op.status != GNTST_eagain)
+                               printk(KERN_ERR "Error mapping the grant 
reference "
+                                      "into the kernel (%d). domid = %d; ref = 
%d\n",
+                                      op.status,
+                                      private_data->grants[slot_index+i]
+                                      .u.valid.domid,
+                                      private_data->grants[slot_index+i]
+                                      .u.valid.ref);
+            else 
+                /* Propagate eagain instead of trying to fix it up */
+                exit_ret = -EAGAIN;
                        goto undo_map_out;
                }
 
@@ -682,6 +687,9 @@ static int gntdev_mmap (struct file *fli
                                       .valid.domid,
                                       private_data->grants[slot_index+i].u
                                       .valid.ref);
+                /* This should never happen after we've mapped into 
+                 * the kernel space. */
+                BUG_ON(op.status == GNTST_eagain);
                                goto undo_map_out;
                        }
                        
@@ -705,9 +713,10 @@ static int gntdev_mmap (struct file *fli
                }
 
        }
+    exit_ret = 0;
 
        up_write(&private_data->grants_sem);
-       return 0;
+       return exit_ret;
 
 undo_map_out:
        /* If we have a mapping failure, the unmapping will be taken care of
@@ -725,7 +734,7 @@ undo_map_out:
        
        up_write(&private_data->grants_sem);
 
-       return -ENOMEM;
+       return exit_ret;
 }
 
 static pte_t gntdev_clear_pte(struct vm_area_struct *vma, unsigned long addr,
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/scsiback/interface.c
--- a/drivers/xen/scsiback/interface.c  Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/scsiback/interface.c  Thu Dec 17 06:37:50 2009 +0000
@@ -37,6 +37,7 @@
 
 #include <xen/evtchn.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
 
 
 static kmem_cache_t *scsiback_cachep;
@@ -69,8 +70,11 @@ static int map_frontend_page( struct vsc
                                GNTMAP_host_map, ring_ref,
                                info->domid);
 
-       err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       BUG_ON(err);
+    do {
+           err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+           BUG_ON(err);
+        msleep(10);
+    } while(op.status == GNTST_eagain);
 
        if (op.status) {
                printk(KERN_ERR "scsiback: Grant table operation failure !\n");
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/scsiback/scsiback.c
--- a/drivers/xen/scsiback/scsiback.c   Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/scsiback/scsiback.c   Thu Dec 17 06:37:50 2009 +0000
@@ -279,6 +279,17 @@ static int scsiback_gnttab_data_map(vscs
 
                err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, 
nr_segments);
                BUG_ON(err);
+        /* Retry maps with GNTST_eagain */
+        for(i=0; i < nr_segments; i++) {
+            while(unlikely(map[i].status == GNTST_eagain))
+            {
+                msleep(10);
+                       err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, 
+                                                &map[i], 
+                                                1);
+                       BUG_ON(err);
+            }
+        }
 
                for (i = 0; i < nr_segments; i++) {
                        struct page *pg;
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/sfc_netback/accel_xenbus.c
--- a/drivers/xen/sfc_netback/accel_xenbus.c    Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/sfc_netback/accel_xenbus.c    Thu Dec 17 06:37:50 2009 +0000
@@ -24,6 +24,7 @@
 
 #include <xen/evtchn.h>
 #include <linux/mutex.h>
+#include <linux/delay.h>
 
 /* drivers/xen/netback/common.h */
 #include "common.h"
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/sfc_netutil/accel_util.c
--- a/drivers/xen/sfc_netutil/accel_util.c      Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/sfc_netutil/accel_util.c      Thu Dec 17 06:37:50 2009 +0000
@@ -23,6 +23,7 @@
  */
 
 #include <linux/if_ether.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/hypercall.h>
@@ -143,7 +144,7 @@ struct net_accel_valloc_grant_mapping {
 /* Map a series of grants into a contiguous virtual area */
 static void *net_accel_map_grants_valloc(struct xenbus_device *dev, 
                                         unsigned *grants, int npages, 
-                                        unsigned flags, void **priv)
+                                        unsigned flags, void **priv, int 
*errno)
 {
        struct net_accel_valloc_grant_mapping *map;
        struct vm_struct *vm;
@@ -171,11 +172,16 @@ static void *net_accel_map_grants_valloc
 
        /* Do the actual mapping */
        addr = vm->addr;
+    if(errno != NULL) *errno = 0;
        for (i = 0; i < npages; i++) {
                rc = net_accel_map_grant(dev, grants[i], map->grant_handles + 
i, 
                                         addr, NULL, flags);
                if (rc != 0)
+        {
+            if(errno != NULL) 
+                *errno = (rc == GNTST_eagain ? -EAGAIN : -EINVAL);
                        goto undo;
+        }
                addr = (void*)((unsigned long)addr + PAGE_SIZE);
        }
 
@@ -224,8 +230,16 @@ void *net_accel_map_grants_contig(struct
                                unsigned *grants, int npages, 
                                void **priv)
 {
-       return net_accel_map_grants_valloc(dev, grants, npages,
-                                          GNTMAP_host_map, priv);
+    int errno;
+    void *ret;
+
+    do {
+           ret = net_accel_map_grants_valloc(dev, grants, npages,
+                                          GNTMAP_host_map, priv, &errno);
+        if(errno) msleep(10);
+    } while(errno == -EAGAIN);
+
+    return ret;
 }
 EXPORT_SYMBOL(net_accel_map_grants_contig);
 
@@ -241,8 +255,16 @@ void *net_accel_map_iomem_page(struct xe
 void *net_accel_map_iomem_page(struct xenbus_device *dev, int gnt_ref,
                             void **priv)
 {
-       return net_accel_map_grants_valloc(dev, &gnt_ref, 1, 
-                                          GNTMAP_host_map, priv);
+    int errno;
+    void *ret;
+
+       do {
+        ret = net_accel_map_grants_valloc(dev, &gnt_ref, 1, 
+                                          GNTMAP_host_map, priv, &errno);
+        if(errno) msleep(10);
+    } while(errno == -EAGAIN);
+
+    return ret;
 }
 EXPORT_SYMBOL(net_accel_map_iomem_page);
 
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/tpmback/interface.c
--- a/drivers/xen/tpmback/interface.c   Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/tpmback/interface.c   Thu Dec 17 06:37:50 2009 +0000
@@ -12,6 +12,7 @@
  */
 
 #include "common.h"
+#include <linux/delay.h>
 #include <xen/balloon.h>
 #include <xen/gnttab.h>
 
@@ -84,8 +85,11 @@ static int map_frontend_page(tpmif_t *tp
        gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
                          GNTMAP_host_map, shared_page, tpmif->domid);
 
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while(op.status == GNTST_eagain);
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/tpmback/tpmback.c
--- a/drivers/xen/tpmback/tpmback.c     Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/tpmback/tpmback.c     Thu Dec 17 06:37:50 2009 +0000
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/miscdevice.h>
 #include <linux/poll.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <xen/xenbus.h>
 #include <xen/interface/grant_table.h>
@@ -256,10 +257,12 @@ int _packet_write(struct packet *pak,
                gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
-               if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-                                                      &map_op, 1))) {
-                       BUG();
-               }
+        do {
+                   if 
(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+                                                      &map_op, 1)))
+                           BUG();
+            if(map_op.status) msleep(10);
+               } while(map_op.status == GNTST_eagain);
 
                handle = map_op.handle;
 
@@ -394,10 +397,12 @@ static int packet_read_shmem(struct pack
                gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
-               if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-                                                      &map_op, 1))) {
-                       BUG();
-               }
+        do {
+                   if 
(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+                                                      &map_op, 1)))
+                           BUG();
+            if(map_op.status) msleep(10);
+               } while(map_op.status == GNTST_eagain);
 
                if (map_op.status) {
                        DPRINTK(" Grant table operation failure !\n");
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/usbback/interface.c
--- a/drivers/xen/usbback/interface.c   Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/usbback/interface.c   Thu Dec 17 06:37:50 2009 +0000
@@ -43,6 +43,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/delay.h>
 #include "usbback.h"
 
 static LIST_HEAD(usbif_list);
@@ -109,8 +110,12 @@ static int map_frontend_pages(usbif_t *u
        gnttab_set_map_op(&op, (unsigned long)usbif->urb_ring_area->addr,
                          GNTMAP_host_map, urb_ring_ref, usbif->domid);
 
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while (op.status == GNTST_eagain);
 
        if (op.status) {
                printk(KERN_ERR "grant table failure mapping urb_ring_ref\n");
@@ -123,8 +128,11 @@ static int map_frontend_pages(usbif_t *u
        gnttab_set_map_op(&op, (unsigned long)usbif->conn_ring_area->addr,
                          GNTMAP_host_map, conn_ring_ref, usbif->domid);
 
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while (op.status == GNTST_eagain);
 
        if (op.status) {
                struct gnttab_unmap_grant_ref unop;
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/usbback/usbback.c
--- a/drivers/xen/usbback/usbback.c     Thu Dec 17 06:37:50 2009 +0000
+++ b/drivers/xen/usbback/usbback.c     Thu Dec 17 06:37:50 2009 +0000
@@ -392,6 +392,16 @@ static int usbbk_gnttab_map(usbif_t *usb
                ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
                                        map, nr_segs);
                BUG_ON(ret);
+        /* Make sure than none of the map ops failed with GNTST_eagain */
+        for( i = 0; i < nr_segs; i++) {
+            while(map[i].status == GNTST_eagain) {
+                msleep(10);
+                       ret = HYPERVISOR_grant_table_op(
+                                GNTTABOP_map_grant_ref,
+                                               &map[i], 1);
+                       BUG_ON(ret);
+            }
+        }
 
                for (i = 0; i < nr_segs; i++) {
                        if (unlikely(map[i].status != 0)) {
diff -r 399c485098f6 -r 65a7b6de9191 drivers/xen/xenbus/xenbus_backend_client.c
--- a/drivers/xen/xenbus/xenbus_backend_client.c        Thu Dec 17 06:37:50 
2009 +0000
+++ b/drivers/xen/xenbus/xenbus_backend_client.c        Thu Dec 17 06:37:50 
2009 +0000
@@ -31,6 +31,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/delay.h>
 #include <xen/gnttab.h>
 #include <xen/xenbus.h>
 #include <xen/driver_util.h>
@@ -48,8 +49,11 @@ struct vm_struct *xenbus_map_ring_valloc
        gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
        
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while(op.status == GNTST_eagain);
 
        if (op.status != GNTST_okay) {
                free_vm_area(area);
@@ -75,8 +79,11 @@ int xenbus_map_ring(struct xenbus_device
        
        gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(10);
+    } while(op.status == GNTST_eagain);
 
        if (op.status != GNTST_okay) {
                xenbus_dev_fatal(dev, op.status,

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