[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |