WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] xenpaging: handle GNTST_eagain in ker

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] xenpaging: handle GNTST_eagain in kernel drivers
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 17 Sep 2010 09:05:04 -0700
Delivery-date: Fri, 17 Sep 2010 09:05:54 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1284739243 -3600
# Node ID 7c7efaea8b54cc05d53ca4a23d9fad0da619bd23
# Parent  039cf55773a9c627844b17a2c2aa2df749807c4c
xenpaging: handle GNTST_eagain in kernel drivers

Handle GNTST_eagain status from GNTTABOP_map_grant_ref and
GNTTABOP_copy operations properly to allow usage of xenpaging without
causing crashes or data corruption.

Remove the existing retry code from net_rx_action(),
dispatch_rw_block_io(), net_accel_map_grants_contig() and
net_accel_map_iomem_page() and replace all relevant
HYPERVISOR_grant_table_op() calls with a retry loop.  This loop is
implemented as a macro to allow different GNTTABOP_* args.  It will
sleep up to 33 seconds and wait for the page to be paged in again.

All ->status checks were updated to use the GNTST_* namespace.  All
return values are converted from GNTST_* namespace to 0/-EINVAL, since
all callers did not use the actual return value.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
Acked-by: Patrick Colp <pjcolp@xxxxxxxxx>
---
 drivers/xen/blkback/blkback.c              |   57 ++++++-----------------------
 drivers/xen/blkback/common.h               |    2 -
 drivers/xen/blkback/interface.c            |   22 +++++------
 drivers/xen/blktap/blktap.c                |   29 ++++++--------
 drivers/xen/blktap/interface.c             |   22 +++++------
 drivers/xen/blktap2/device.c               |   38 +++++++++----------
 drivers/xen/core/gnttab.c                  |    4 +-
 drivers/xen/gntdev/gntdev.c                |   26 ++++++-------
 drivers/xen/netback/interface.c            |   28 +++++---------
 drivers/xen/netback/netback.c              |   52 +++++++-------------------
 drivers/xen/scsiback/interface.c           |   24 +++++-------
 drivers/xen/scsiback/scsiback.c            |   16 ++------
 drivers/xen/sfc_netutil/accel_util.c       |   45 ++++++----------------
 drivers/xen/tpmback/interface.c            |   22 +++++------
 drivers/xen/tpmback/tpmback.c              |   26 ++++---------
 drivers/xen/usbback/interface.c            |   29 +++++---------
 drivers/xen/usbback/usbback.c              |   16 ++------
 drivers/xen/xenbus/xenbus_backend_client.c |   27 ++++++-------
 include/xen/gnttab.h                       |   38 +++++++++++++++++++
 19 files changed, 213 insertions(+), 310 deletions(-)

diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blkback/blkback.c
--- a/drivers/xen/blkback/blkback.c     Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blkback/blkback.c     Fri Sep 17 17:00:43 2010 +0100
@@ -107,7 +107,7 @@ static inline unsigned long vaddr(pendin
 
 
 static int do_block_io_op(blkif_t *blkif);
-static int dispatch_rw_block_io(blkif_t *blkif,
+static void dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req);
 static void make_response(blkif_t *blkif, u64 id,
@@ -312,13 +312,13 @@ static int do_block_io_op(blkif_t *blkif
        blkif_request_t req;
        pending_req_t *pending_req;
        RING_IDX rc, rp;
-       int more_to_do = 0, ret;
+       int more_to_do = 0;
 
        rc = blk_rings->common.req_cons;
        rp = blk_rings->common.sring->req_prod;
        rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-       while ((rc != rp) || (blkif->is_suspended_req)) {
+       while ((rc != rp)) {
 
                if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
                        break;
@@ -335,14 +335,6 @@ static int do_block_io_op(blkif_t *blkif
                        break;
                }
 
-        /* Handle the suspended request first, if one exists */
-        if(blkif->is_suspended_req)
-        {
-            memcpy(&req, &blkif->suspended_req, sizeof(req));
-            blkif->is_suspended_req = 0;
-            goto handle_request;
-        }
-
                switch (blkif->blk_protocol) {
                case BLKIF_PROTOCOL_NATIVE:
                        memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc), 
sizeof(req));
@@ -361,19 +353,17 @@ static int do_block_io_op(blkif_t *blkif
                /* Apply all sanity checks to /private copy/ of request. */
                barrier();
 
-handle_request:
-        ret = 0;
                switch (req.operation) {
                case BLKIF_OP_READ:
                        blkif->st_rd_req++;
-                       ret = dispatch_rw_block_io(blkif, &req, pending_req); 
+                       dispatch_rw_block_io(blkif, &req, pending_req);
                        break;
                case BLKIF_OP_WRITE_BARRIER:
                        blkif->st_br_req++;
                        /* fall through */
                case BLKIF_OP_WRITE:
                        blkif->st_wr_req++;
-                       ret = dispatch_rw_block_io(blkif, &req, pending_req);
+                       dispatch_rw_block_io(blkif, &req, pending_req);
                        break;
                default:
                        /* A good sign something is wrong: sleep for a while to
@@ -386,17 +376,6 @@ handle_request:
                        free_req(pending_req);
                        break;
                }
-        BUG_ON(ret != 0 && ret != -EAGAIN);
-        /* If we can't handle the request at the moment, save it, and break the
-         * loop */ 
-        if(ret == -EAGAIN)
-        {
-            memcpy(&blkif->suspended_req, &req, sizeof(req));
-            blkif->is_suspended_req = 1;
-            /* Return "no more work pending", restart will be handled 'out of
-             * band' */
-            return 0;
-        }
 
                /* Yield point for this unbounded loop. */
                cond_resched();
@@ -405,7 +384,7 @@ handle_request:
        return more_to_do;
 }
 
-static int dispatch_rw_block_io(blkif_t *blkif,
+static void dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req)
 {
@@ -474,15 +453,13 @@ static int dispatch_rw_block_io(blkif_t 
        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
        BUG_ON(ret);
 
-#define GENERAL_ERR   (1<<0)
-#define EAGAIN_ERR    (1<<1)
        for (i = 0; i < nseg; i++) {
-               if (unlikely(map[i].status != 0)) {
+               if (unlikely(map[i].status == GNTST_eagain))
+                       
gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &map[i])
+               if (unlikely(map[i].status != GNTST_okay)) {
                        DPRINTK("invalid buffer -- could not remap it\n");
                        map[i].handle = BLKBACK_INVALID_HANDLE;
-                       ret |= GENERAL_ERR;
-            if(map[i].status == GNTST_eagain)
-                           ret |= EAGAIN_ERR;
+                       ret = 1;
                } else {
                        blkback_pagemap_set(vaddr_pagenr(pending_req, i),
                                            pending_page(pending_req, i),
@@ -501,14 +478,6 @@ static int dispatch_rw_block_io(blkif_t 
                seg[i].buf  = map[i].dev_bus_addr | 
                        (req->seg[i].first_sect << 9);
        }
-
-    /* If any of grant maps failed with GNTST_eagain, suspend and retry later 
*/
-    if(ret & EAGAIN_ERR)
-    {
-        fast_flush_area(pending_req);
-        free_req(pending_req);
-        return -EAGAIN;
-    }
 
        if (ret)
                goto fail_flush;
@@ -575,7 +544,7 @@ static int dispatch_rw_block_io(blkif_t 
        else if (operation == WRITE || operation == WRITE_BARRIER)
                blkif->st_wr_sect += preq.nr_sects;
 
-       return 0;
+       return;
 
  fail_flush:
        fast_flush_area(pending_req);
@@ -583,7 +552,7 @@ static int dispatch_rw_block_io(blkif_t 
        make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
        free_req(pending_req);
        msleep(1); /* back off a bit */
-       return 0;
+       return;
 
  fail_put_bio:
        __end_block_io_op(pending_req, -EINVAL);
@@ -591,7 +560,7 @@ static int dispatch_rw_block_io(blkif_t 
                bio_put(bio);
        unplug_queue(blkif);
        msleep(1); /* back off a bit */
-       return 0;
+       return;
 }
 
 
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blkback/common.h
--- a/drivers/xen/blkback/common.h      Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blkback/common.h      Fri Sep 17 17:00:43 2010 +0100
@@ -83,8 +83,6 @@ typedef struct blkif_st {
        struct task_struct  *xenblkd;
        unsigned int        waiting_reqs;
        request_queue_t     *plug;
-    int                 is_suspended_req;
-    blkif_request_t     suspended_req;
 
        /* statistics */
        unsigned long       st_print;
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blkback/interface.c
--- a/drivers/xen/blkback/interface.c   Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blkback/interface.c   Fri Sep 17 17:00:43 2010 +0100
@@ -59,25 +59,23 @@ static int map_frontend_page(blkif_t *bl
 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op;
+       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(100);
-    } while(op.status == GNTST_eagain);
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
-       if (op.status) {
-               DPRINTK(" Grant table operation failure !\n");
-               return op.status;
+       if (op.status == GNTST_okay) {
+               blkif->shmem_ref = shared_page;
+               blkif->shmem_handle = op.handle;
+               ret = 0;
+       } else {
+               DPRINTK(" Grant table operation failure %d!\n", (int)op.status);
+               ret = -EINVAL;
        }
 
-       blkif->shmem_ref = shared_page;
-       blkif->shmem_handle = op.handle;
-
-       return 0;
+       return ret;
 }
 
 static void unmap_frontend_page(blkif_t *blkif)
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blktap/blktap.c       Fri Sep 17 17:00:43 2010 +0100
@@ -1526,19 +1526,17 @@ static void dispatch_rw_block_io(blkif_t
 
                        uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
 
-                       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;
+                       gnttab_check_GNTST_eagain_while(GNTTABOP_map_grant_ref, 
&map[i]);
+
+                       if (unlikely(map[i].status != GNTST_okay)) {
+                               WPRINTK("invalid kernel buffer -- could not 
remap it\n");
+                               ret = 1;
                                map[i].handle = INVALID_GRANT_HANDLE;
                        }
 
-                       if (unlikely(map[i+1].status != 0)) {
-                               WPRINTK("invalid user buffer -- "
-                                       "could not remap it\n");
-                               ret |= 1;
+                       if (unlikely(map[i+1].status != GNTST_okay)) {
+                               WPRINTK("invalid kernel buffer -- could not 
remap it\n");
+                               ret = 1;
                                map[i+1].handle = INVALID_GRANT_HANDLE;
                        }
 
@@ -1565,12 +1563,11 @@ static void dispatch_rw_block_io(blkif_t
 
                        uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
 
-                       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;
+                       gnttab_check_GNTST_eagain_while(GNTTABOP_map_grant_ref, 
&map[i]);
+
+                       if (unlikely(map[i].status != GNTST_okay)) {
+                               WPRINTK("invalid kernel buffer -- could not 
remap it\n");
+                               ret = 1;
                                map[i].handle = INVALID_GRANT_HANDLE;
                        }
 
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blktap/interface.c
--- a/drivers/xen/blktap/interface.c    Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blktap/interface.c    Fri Sep 17 17:00:43 2010 +0100
@@ -59,25 +59,23 @@ static int map_frontend_page(blkif_t *bl
 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op;
+       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
-       if (op.status) {
-               DPRINTK(" Grant table operation failure !\n");
-               return op.status;
+       if (op.status == GNTST_okay) {
+               blkif->shmem_ref = shared_page;
+               blkif->shmem_handle = op.handle;
+               ret = 0;
+       } else {
+               DPRINTK("Grant table operation failure %d!\n", (int)op.status);
+               ret = -EINVAL;
        }
 
-       blkif->shmem_ref = shared_page;
-       blkif->shmem_handle = op.handle;
-
-       return 0;
+       return ret;
 }
 
 static void unmap_frontend_page(blkif_t *blkif)
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/blktap2/device.c
--- a/drivers/xen/blktap2/device.c      Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/blktap2/device.c      Fri Sep 17 17:00:43 2010 +0100
@@ -505,10 +505,10 @@ blktap_map_foreign(struct blktap *tap,
 
                uvaddr = MMAP_VADDR(ring->user_vstart, usr_idx, i);
 
-               if (unlikely(table->grants[grant].status)) {
+               if (unlikely(table->grants[grant].status != GNTST_okay)) {
                        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);
+                       /* 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;
                }
@@ -517,19 +517,18 @@ blktap_map_foreign(struct blktap *tap,
                foreign_mfn = table->grants[grant].dev_bus_addr >> PAGE_SHIFT;
                grant++;
 
-               if (xen_feature(XENFEAT_auto_translated_physmap))
-                       goto done;
-
-               if (unlikely(table->grants[grant].status)) {
-                       BTERR("invalid user buffer: could not remap it\n");
-                       err |= 1;
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       if (unlikely(table->grants[grant].status != 
GNTST_okay)) {
+                               /* This should never happen: blkback should 
handle eagain first */
+                               WARN_ON(table->grants[grant].status == 
GNTST_eagain);
+                               BTERR("invalid user buffer: could not remap 
it\n");
+                               err |= 1;
+                       }
                        table->grants[grant].handle = INVALID_GRANT_HANDLE;
-               }
-
-               request->handles[i].user = table->grants[grant].handle;
-               grant++;
-
-       done:
+                       request->handles[i].user = table->grants[grant].handle;
+                       grant++;
+               }
+
                if (err)
                        continue;
 
@@ -602,11 +601,10 @@ blktap_map(struct blktap *tap,
                set_page_private(tap_page, page_private(page));
                SetPageBlkback(tap_page);
 
-               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);
+               gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, 
&map);
+
+               /* 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 039cf55773a9 -r 7c7efaea8b54 drivers/xen/core/gnttab.c
--- a/drivers/xen/core/gnttab.c Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/core/gnttab.c Fri Sep 17 17:00:43 2010 +0100
@@ -487,7 +487,7 @@ static int gnttab_map(unsigned int start
                return -ENOSYS;
        }
 
-       BUG_ON(rc || setup.status);
+       BUG_ON(rc || setup.status != GNTST_okay);
 
        if (shared == NULL)
                shared = arch_gnttab_alloc_shared(frames);
@@ -571,7 +571,7 @@ int gnttab_copy_grant_page(grant_ref_t r
        err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_and_replace,
                                        &unmap, 1);
        BUG_ON(err);
-       BUG_ON(unmap.status);
+       BUG_ON(unmap.status != GNTST_okay);
 
        write_sequnlock(&gnttab_dma_lock);
 
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/gntdev/gntdev.c
--- a/drivers/xen/gntdev/gntdev.c       Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/gntdev/gntdev.c       Fri Sep 17 17:00:43 2010 +0100
@@ -578,7 +578,7 @@ static int gntdev_mmap (struct file *fli
        vma->vm_mm->context.has_foreign_mappings = 1;
 #endif
 
-    exit_ret = -ENOMEM;
+       exit_ret = -ENOMEM;
        for (i = 0; i < size; ++i) {
 
                flags = GNTMAP_host_map;
@@ -599,8 +599,8 @@ static int gntdev_mmap (struct file *fli
                ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, 
                                                &op, 1);
                BUG_ON(ret);
-               if (op.status) {
-            if(op.status != GNTST_eagain)
+               if (op.status != GNTST_okay) {
+                       if (op.status != GNTST_eagain)
                                printk(KERN_ERR "Error mapping the grant 
reference "
                                       "into the kernel (%d). domid = %d; ref = 
%d\n",
                                       op.status,
@@ -608,9 +608,9 @@ static int gntdev_mmap (struct file *fli
                                       .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;
+                       else
+                               /* Propagate eagain instead of trying to fix it 
up */
+                               exit_ret = -EAGAIN;
                        goto undo_map_out;
                }
 
@@ -679,7 +679,7 @@ static int gntdev_mmap (struct file *fli
                        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
                                                        &op, 1);
                        BUG_ON(ret);
-                       if (op.status) {
+                       if (op.status != GNTST_okay) {
                                printk(KERN_ERR "Error mapping the grant "
                                       "reference into user space (%d). domid "
                                       "= %d; ref = %d\n", op.status,
@@ -687,9 +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);
+                               /* This should never happen after we've mapped 
into
+                               * the kernel space. */
+                               BUG_ON(op.status == GNTST_eagain);
                                goto undo_map_out;
                        }
                        
@@ -713,7 +713,7 @@ static int gntdev_mmap (struct file *fli
                }
 
        }
-    exit_ret = 0;
+       exit_ret = 0;
 
        up_write(&private_data->grants_sem);
        return exit_ret;
@@ -785,7 +785,7 @@ static pte_t gntdev_clear_pte(struct vm_
                        ret = HYPERVISOR_grant_table_op(
                                GNTTABOP_unmap_grant_ref, &op, 1);
                        BUG_ON(ret);
-                       if (op.status)
+                       if (op.status != GNTST_okay)
                                printk("User unmap grant status = %d\n", 
                                       op.status);
                } else {
@@ -802,7 +802,7 @@ static pte_t gntdev_clear_pte(struct vm_
                ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, 
                                                &op, 1);
                BUG_ON(ret);
-               if (op.status)
+               if (op.status != GNTST_okay)
                        printk("Kernel unmap grant status = %d\n", op.status);
 
 
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/netback/interface.c
--- a/drivers/xen/netback/interface.c   Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/netback/interface.c   Fri Sep 17 17:00:43 2010 +0100
@@ -251,15 +251,11 @@ static int map_frontend_pages(
 
        gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
                          GNTMAP_host_map, tx_ring_ref, netif->domid);
-    do {
-               if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                       BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
-
-       if (op.status) { 
-               DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
-               return op.status;
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
+
+       if (op.status != GNTST_okay) {
+               DPRINTK(" Gnttab failure mapping tx_ring_ref %d!\n", 
(int)op.status);
+               return -EINVAL;
        }
 
        netif->tx_shmem_ref    = tx_ring_ref;
@@ -267,13 +263,9 @@ static int map_frontend_pages(
 
        gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
                          GNTMAP_host_map, rx_ring_ref, netif->domid);
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
-
-       if (op.status) {
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
+
+       if (op.status != GNTST_okay) {
                struct gnttab_unmap_grant_ref unop;
 
                gnttab_set_unmap_op(&unop,
@@ -281,8 +273,8 @@ static int map_frontend_pages(
                                    GNTMAP_host_map, netif->tx_shmem_handle);
                VOID(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
                                               &unop, 1));
-               DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
-               return op.status;
+               DPRINTK(" Gnttab failure mapping rx_ring_ref %d!\n", 
(int)op.status);
+               return -EINVAL;
        }
 
        netif->rx_shmem_ref    = rx_ring_ref;
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/netback/netback.c     Fri Sep 17 17:00:43 2010 +0100
@@ -494,8 +494,7 @@ static inline void netbk_free_pages(int 
    used to set up the operations on the top of
    netrx_pending_operations, which have since been done.  Check that
    they didn't give any errors and advance over them. */
-static int netbk_check_gop(int nr_frags, domid_t domid,
-                          struct netrx_pending_operations *npo, int *eagain)
+static int netbk_check_gop(int nr_frags, domid_t domid, struct 
netrx_pending_operations *npo)
 {
        multicall_entry_t *mcl;
        gnttab_transfer_t *gop;
@@ -503,17 +502,15 @@ static int netbk_check_gop(int nr_frags,
        int status = NETIF_RSP_OKAY;
        int i;
 
-    *eagain = 0;
-
        for (i = 0; i <= nr_frags; i++) {
                if (npo->meta[npo->meta_cons + i].copy) {
                        copy_op = npo->copy + npo->copy_cons++;
-                       if (copy_op->status != GNTST_okay) {
+                       if (unlikely(copy_op->status == GNTST_eagain))
+                               gnttab_check_GNTST_eagain_while(GNTTABOP_copy, 
copy_op);
+                       if (unlikely(copy_op->status != GNTST_okay)) {
                                DPRINTK("Bad status %d from copy to DOM%d.\n",
                                        copy_op->status, domid);
                                status = NETIF_RSP_ERROR;
-                if(copy_op->status == GNTST_eagain)
-                    *eagain = 1;
                        }
                } else {
                        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -524,7 +521,7 @@ static int netbk_check_gop(int nr_frags,
 
                        gop = npo->trans + npo->trans_cons++;
                        /* Check the reassignment error code. */
-                       if (gop->status != 0) {
+                       if (unlikely(gop->status != GNTST_okay)) {
                                DPRINTK("Bad status %d from grant transfer to 
DOM%u\n",
                                        gop->status, domid);
                                /*
@@ -533,8 +530,6 @@ static int netbk_check_gop(int nr_frags,
                                 * a fatal error anyway.
                                 */
                                BUG_ON(gop->status == GNTST_bad_page);
-                if(gop->status == GNTST_eagain)
-                    *eagain = 1;
                                status = NETIF_RSP_ERROR;
                        }
                }
@@ -576,7 +571,6 @@ static void net_rx_action(unsigned long 
        int nr_frags;
        int count;
        unsigned long offset;
-    int eagain;
 
        /*
         * Putting hundreds of bytes on the stack is considered rude.
@@ -680,7 +674,7 @@ static void net_rx_action(unsigned long 
 
                netif = netdev_priv(skb->dev);
 
-               status = netbk_check_gop(nr_frags, netif->domid, &npo, &eagain);
+               status = netbk_check_gop(nr_frags, netif->domid, &npo);
 
                /* We can't rely on skb_release_data to release the
                   pages used by fragments for us, since it tries to
@@ -691,22 +685,14 @@ static void net_rx_action(unsigned long 
                /* (Freeing the fragments is safe since we copy
                   non-linear skbs destined for flipping interfaces) */
                if (!netif->copying_receiver) {
-            /* 
-             * Cannot handle failed grant transfers at the moment (because
-             * mmu_updates likely completed)
-             */
-            BUG_ON(eagain);
                        atomic_set(&(skb_shinfo(skb)->dataref), 1);
                        skb_shinfo(skb)->frag_list = NULL;
                        skb_shinfo(skb)->nr_frags = 0;
                        netbk_free_pages(nr_frags, meta + npo.meta_cons + 1);
                }
 
-        if(!eagain)
-        {
-                   netif->stats.tx_bytes += skb->len;
-                   netif->stats.tx_packets++;
-        }
+               netif->stats.tx_bytes += skb->len;
+               netif->stats.tx_packets++;
 
                id = meta[npo.meta_cons].id;
                flags = nr_frags ? NETRXF_more_data : 0;
@@ -756,18 +742,8 @@ static void net_rx_action(unsigned long 
                    !netbk_queue_full(netif))
                        netif_wake_queue(netif->dev);
 
-        if(!eagain || netbk_queue_full(netif))
-        {
-                   netif_put(netif);
-                   dev_kfree_skb(skb);
-                   netif->stats.tx_dropped += !!eagain;
-        } 
-        else
-        {
-               netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 +
-                                  !!skb_shinfo(skb)->gso_size;
-            skb_queue_head(&rx_queue, skb);
-        }
+               netif_put(netif);
+               dev_kfree_skb(skb);
 
                npo.meta_cons += nr_frags + 1;
        }
@@ -1109,7 +1085,7 @@ static int netbk_tx_check_mop(struct sk_
 
        /* Check status of header. */
        err = mop->status;
-       if (unlikely(err)) {
+       if (unlikely(err != GNTST_okay)) {
                txp = &pending_tx_info[pending_idx].req;
                make_tx_response(netif, txp, NETIF_RSP_ERROR);
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
@@ -1130,12 +1106,12 @@ static int netbk_tx_check_mop(struct sk_
 
                /* Check error status: if okay then remember grant handle. */
                newerr = (++mop)->status;
-               if (likely(!newerr)) {
+               if (likely(newerr == GNTST_okay)) {
                        set_phys_to_machine(idx_to_pfn(pending_idx),
                                FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
                        grant_tx_handle[pending_idx] = mop->handle;
                        /* Had a previous error? Invalidate this fragment. */
-                       if (unlikely(err))
+                       if (unlikely(err != GNTST_okay))
                                netif_idx_release(pending_idx);
                        continue;
                }
@@ -1147,7 +1123,7 @@ static int netbk_tx_check_mop(struct sk_
                netif_put(netif);
 
                /* Not the first error? Preceding frags already invalidated. */
-               if (err)
+               if (err != GNTST_okay)
                        continue;
 
                /* First error: invalidate header and preceding fragments. */
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/scsiback/interface.c
--- a/drivers/xen/scsiback/interface.c  Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/scsiback/interface.c  Fri Sep 17 17:00:43 2010 +0100
@@ -64,27 +64,23 @@ static int map_frontend_page( struct vsc
                                unsigned long ring_ref)
 {
        struct gnttab_map_grant_ref op;
-       int err;
+       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)info->ring_area->addr,
                                GNTMAP_host_map, ring_ref,
                                info->domid);
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
-    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");
-               return op.status;
+       if (op.status != GNTST_okay) {
+               printk(KERN_ERR "scsiback: Grant table operation failure 
%d!\n", (int)op.status);
+               ret = -EINVAL;
+       } else {
+               info->shmem_ref    = ring_ref;
+               info->shmem_handle = op.handle;
+               ret = 0;
        }
 
-       info->shmem_ref    = ring_ref;
-       info->shmem_handle = op.handle;
-
-       return (GNTST_okay);
+       return ret;
 }
 
 static void unmap_frontend_page(struct vscsibk_info *info)
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/scsiback/scsiback.c
--- a/drivers/xen/scsiback/scsiback.c   Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/scsiback/scsiback.c   Fri Sep 17 17:00:43 2010 +0100
@@ -279,22 +279,14 @@ 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;
 
-                       if (unlikely(map[i].status != 0)) {
+                       /* Retry maps with GNTST_eagain */
+                       if (unlikely(map[i].status == GNTST_eagain))
+                               
gnttab_check_GNTST_eagain_while(GNTTABOP_map_grant_ref, &map[i]);
+                       if (unlikely(map[i].status != GNTST_okay)) {
                                printk(KERN_ERR "scsiback: invalid buffer -- 
could not remap it\n");
                                map[i].handle = SCSIBACK_INVALID_HANDLE;
                                err |= 1;
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/sfc_netutil/accel_util.c
--- a/drivers/xen/sfc_netutil/accel_util.c      Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/sfc_netutil/accel_util.c      Fri Sep 17 17:00:43 2010 +0100
@@ -71,24 +71,27 @@ static int net_accel_map_grant(struct xe
                               u64 *dev_bus_addr, unsigned flags)
 {
        struct gnttab_map_grant_ref op;
+       int ret;
        
        gnttab_set_map_op(&op, (unsigned long)vaddr, flags,
                          gnt_ref, dev->otherend_id);
 
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
        if (op.status != GNTST_okay) {
                xenbus_dev_error
                        (dev, op.status,
                         "failed mapping in shared page %d from domain %d\n",
                         gnt_ref, dev->otherend_id);
+               ret = -EINVAL;
        } else {
                *handle = op.handle;
                if (dev_bus_addr)
                        *dev_bus_addr = op.dev_bus_addr;
-       }
-
-       return op.status;
+               ret = 0;
+       }
+
+       return ret;
 }
 
 
@@ -112,7 +115,7 @@ static int net_accel_unmap_grant(struct 
                                 "failed unmapping page at handle %d error 
%d\n",
                                 handle, op.status);
 
-       return op.status;
+       return op.status == GNTST_okay ? 0 : -EINVAL;
 }
 
 
@@ -144,7 +147,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, int 
*errno)
+                                        unsigned flags, void **priv)
 {
        struct net_accel_valloc_grant_mapping *map;
        struct vm_struct *vm;
@@ -172,16 +175,12 @@ 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);
+               if (rc < 0)
                        goto undo;
-        }
                addr = (void*)((unsigned long)addr + PAGE_SIZE);
        }
 
@@ -230,16 +229,7 @@ void *net_accel_map_grants_contig(struct
                                unsigned *grants, int npages, 
                                void **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;
+    return net_accel_map_grants_valloc(dev, grants, npages, GNTMAP_host_map, 
priv);
 }
 EXPORT_SYMBOL(net_accel_map_grants_contig);
 
@@ -255,16 +245,7 @@ void *net_accel_map_iomem_page(struct xe
 void *net_accel_map_iomem_page(struct xenbus_device *dev, int gnt_ref,
                             void **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;
+       return net_accel_map_grants_valloc(dev, &gnt_ref, 1, GNTMAP_host_map, 
priv);
 }
 EXPORT_SYMBOL(net_accel_map_iomem_page);
 
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/tpmback/interface.c
--- a/drivers/xen/tpmback/interface.c   Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/tpmback/interface.c   Fri Sep 17 17:00:43 2010 +0100
@@ -81,25 +81,23 @@ static int map_frontend_page(tpmif_t *tp
 static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op;
+       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
                          GNTMAP_host_map, shared_page, tpmif->domid);
 
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
-       if (op.status) {
-               DPRINTK(" Grant table operation failure !\n");
-               return op.status;
+       if (op.status != GNTST_okay) {
+               DPRINTK(" Grant table operation failure %d!\n", (int)op.status);
+               ret = -EINVAL;
+       } else {
+               tpmif->shmem_ref = shared_page;
+               tpmif->shmem_handle = op.handle;
+               ret = 0;
        }
 
-       tpmif->shmem_ref = shared_page;
-       tpmif->shmem_handle = op.handle;
-
-       return 0;
+       return ret;
 }
 
 static void unmap_frontend_page(tpmif_t *tpmif)
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/tpmback/tpmback.c
--- a/drivers/xen/tpmback/tpmback.c     Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/tpmback/tpmback.c     Fri Sep 17 17:00:43 2010 +0100
@@ -257,19 +257,14 @@ int _packet_write(struct packet *pak,
                gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
-        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;
-
-               if (map_op.status) {
+               gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, 
&map_op);
+
+               if (map_op.status != GNTST_okay) {
                        DPRINTK(" Grant table operation failure !\n");
                        return 0;
                }
+
+               handle = map_op.handle;
 
                tocopy = min_t(size_t, size - offset, PAGE_SIZE);
 
@@ -397,14 +392,9 @@ 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);
 
-        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) {
+               gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, 
&map_op);
+
+               if (map_op.status != GNTST_okay) {
                        DPRINTK(" Grant table operation failure !\n");
                        return -EFAULT;
                }
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/usbback/interface.c
--- a/drivers/xen/usbback/interface.c   Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/usbback/interface.c   Fri Sep 17 17:00:43 2010 +0100
@@ -110,16 +110,11 @@ 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);
 
-
-    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");
-               return op.status;
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
+
+       if (op.status != GNTST_okay) {
+               printk(KERN_ERR "grant table failure mapping urb_ring_ref 
%d\n", (int)op.status);
+               return -EINVAL;
        }
 
        usbif->urb_shmem_ref = urb_ring_ref;
@@ -128,21 +123,17 @@ 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);
 
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while (op.status == GNTST_eagain);
-
-       if (op.status) {
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
+
+       if (op.status != GNTST_okay) {
                struct gnttab_unmap_grant_ref unop;
                gnttab_set_unmap_op(&unop,
                                (unsigned long) usbif->urb_ring_area->addr,
                                GNTMAP_host_map, usbif->urb_shmem_handle);
                VOID(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &unop,
                                1));
-               printk(KERN_ERR "grant table failure mapping conn_ring_ref\n");
-               return op.status;
+               printk(KERN_ERR "grant table failure mapping conn_ring_ref 
%d\n", (int)op.status);
+               return -EINVAL;
        }
 
        usbif->conn_shmem_ref = conn_ring_ref;
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/usbback/usbback.c
--- a/drivers/xen/usbback/usbback.c     Wed Sep 15 07:46:47 2010 +0100
+++ b/drivers/xen/usbback/usbback.c     Fri Sep 17 17:00:43 2010 +0100
@@ -392,19 +392,13 @@ 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)) {
+                       /* Make sure than none of the map ops failed with 
GNTST_eagain */
+                       if (unlikely(map[i].status == GNTST_eagain))
+                               
gnttab_check_GNTST_eagain_while(GNTTABOP_map_grant_ref, &map[i]);
+
+                       if (unlikely(map[i].status != GNTST_okay)) {
                                printk(KERN_ERR "usbback: invalid buffer -- 
could not remap it\n");
                                map[i].handle = USBBACK_INVALID_HANDLE;
                                ret |= 1;
diff -r 039cf55773a9 -r 7c7efaea8b54 drivers/xen/xenbus/xenbus_backend_client.c
--- a/drivers/xen/xenbus/xenbus_backend_client.c        Wed Sep 15 07:46:47 
2010 +0100
+++ b/drivers/xen/xenbus/xenbus_backend_client.c        Fri Sep 17 17:00:43 
2010 +0100
@@ -49,11 +49,7 @@ struct vm_struct *xenbus_map_ring_valloc
        gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
        
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
        if (op.status != GNTST_okay) {
                free_vm_area(area);
@@ -61,7 +57,7 @@ struct vm_struct *xenbus_map_ring_valloc
                                 "mapping in shared page %d from domain %d",
                                 gnt_ref, dev->otherend_id);
                BUG_ON(!IS_ERR(ERR_PTR(op.status)));
-               return ERR_PTR(op.status);
+               return ERR_PTR(-EINVAL);
        }
 
        /* Stuff the handle in an unused field */
@@ -76,23 +72,24 @@ int xenbus_map_ring(struct xenbus_device
                   grant_handle_t *handle, void *vaddr)
 {
        struct gnttab_map_grant_ref op;
+       int ret;
        
        gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
-    do {
-           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-                   BUG();
-        msleep(10);
-    } while(op.status == GNTST_eagain);
+
+       gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
 
        if (op.status != GNTST_okay) {
                xenbus_dev_fatal(dev, op.status,
                                 "mapping in shared page %d from domain %d",
                                 gnt_ref, dev->otherend_id);
-       } else
+               ret = -EINVAL;
+       } else {
                *handle = op.handle;
+               ret = 0;
+       }
 
-       return op.status;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(xenbus_map_ring);
 
@@ -115,7 +112,7 @@ int xenbus_unmap_ring_vfree(struct xenbu
                                 "unmapping page at handle %d error %d",
                                 (int16_t)area->phys_addr, op.status);
 
-       return op.status;
+       return op.status == GNTST_okay ? 0 : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
 
@@ -135,7 +132,7 @@ int xenbus_unmap_ring(struct xenbus_devi
                                 "unmapping page at handle %d error %d",
                                 handle, op.status);
 
-       return op.status;
+       return op.status == GNTST_okay ? 0 : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
 
diff -r 039cf55773a9 -r 7c7efaea8b54 include/xen/gnttab.h
--- a/include/xen/gnttab.h      Wed Sep 15 07:46:47 2010 +0100
+++ b/include/xen/gnttab.h      Fri Sep 17 17:00:43 2010 +0100
@@ -40,6 +40,7 @@
 #include <asm/hypervisor.h>
 #include <asm/maddr.h> /* maddr_t */
 #include <linux/mm.h>
+#include <linux/delay.h>
 #include <xen/interface/grant_table.h>
 #include <xen/features.h>
 
@@ -161,4 +162,41 @@ gnttab_set_replace_op(struct gnttab_unma
        unmap->handle = handle;
 }
 
+#define gnttab_check_GNTST_eagain_while(__HCop, __HCarg_p)                     
\
+{                                                                              
\
+       u8 __hc_delay = 1;                                                      
\
+       int __ret;                                                              
\
+       while (unlikely((__HCarg_p)->status == GNTST_eagain && __hc_delay)) {   
\
+               msleep(__hc_delay++);                                           
\
+               __ret = HYPERVISOR_grant_table_op(__HCop, (__HCarg_p), 1);      
\
+               BUG_ON(__ret);                                                  
\
+       }                                                                       
\
+       if (__hc_delay == 0) {                                                  
\
+               printk(KERN_ERR "%s: %s gnt busy\n", __func__, current->comm);  
\
+               (__HCarg_p)->status = GNTST_bad_page;                           
\
+       }                                                                       
\
+       if ((__HCarg_p)->status != GNTST_okay)                                  
\
+               printk(KERN_ERR "%s: %s gnt status %x\n",                       
\
+                       __func__, current->comm, (__HCarg_p)->status);          
\
+}
+
+#define gnttab_check_GNTST_eagain_do_while(__HCop, __HCarg_p)                  
\
+{                                                                              
\
+       u8 __hc_delay = 1;                                                      
\
+       int __ret;                                                              
\
+       do {                                                                    
\
+               __ret = HYPERVISOR_grant_table_op(__HCop, (__HCarg_p), 1);      
\
+               BUG_ON(__ret);                                                  
\
+               if ((__HCarg_p)->status == GNTST_eagain)                        
\
+                       msleep(__hc_delay++);                                   
\
+       } while ((__HCarg_p)->status == GNTST_eagain && __hc_delay);            
\
+       if (__hc_delay == 0) {                                                  
\
+               printk(KERN_ERR "%s: %s gnt busy\n", __func__, current->comm);  
\
+               (__HCarg_p)->status = GNTST_bad_page;                           
\
+       }                                                                       
\
+       if ((__HCarg_p)->status != GNTST_okay)                                  
\
+               printk(KERN_ERR "%s: %s gnt status %x\n",                       
\
+                       __func__, current->comm, (__HCarg_p)->status);          
\
+}
+
 #endif /* __ASM_GNTTAB_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] xenpaging: handle GNTST_eagain in kernel drivers, Xen patchbot-linux-2.6.18-xen <=