# 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
|