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

[Xen-devel] Re: [PATCH] xenpaging: handle GNTST_eagain in kernel drivers



Is there any particular reason for 33 seconds? This number seems a bit
high to me. Did you run into situations where that amount of time was
needed? Otherwise I'm happy with everything. Thanks for all the hard
work!

Acked-by: Patrick Colp <pjcolp@xxxxxxxxx>


Patrick


On 15 September 2010 09:08, Olaf Hering <olaf@xxxxxxxxx> wrote:
>
> 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>
>
> ---
> Compiled with x86_64 and i386 configs
>
> Â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        |  34 ++++++++---------
> Âdrivers/xen/core/gnttab.c         Â|  Â4 +-
> Âdrivers/xen/gntdev/gntdev.c        Â|  26 ++++++-------
> Âdrivers/xen/netback/interface.c      Â|  26 ++++---------
> Â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    |  41 +++++---------------
> Âdrivers/xen/tpmback/interface.c      Â|  22 +++++------
> Âdrivers/xen/tpmback/tpmback.c       Â|  22 +++--------
> Âdrivers/xen/usbback/interface.c      Â|  25 ++++--------
> Âdrivers/xen/usbback/usbback.c       Â|  16 ++------
> Âdrivers/xen/xenbus/xenbus_backend_client.c | Â 27 ++++++-------
> Âinclude/xen/gnttab.h            |  38 +++++++++++++++++++
> Â19 files changed, 204 insertions(+), 301 deletions(-)
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blkback/blkback.c
> +++ linux-2.6.18-xen.hg/drivers/xen/blkback/blkback.c
> @@ -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),
> @@ -502,14 +479,6 @@ static int dispatch_rw_block_io(blkif_t
> Â Â Â Â Â Â Â Â Â Â Â Â(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;
> Â}
>
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blkback/common.h
> +++ linux-2.6.18-xen.hg/drivers/xen/blkback/common.h
> @@ -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;
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blkback/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/blkback/interface.c
> @@ -59,25 +59,23 @@ blkif_t *blkif_alloc(domid_t domid)
> Â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)
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blktap/blktap.c
> +++ linux-2.6.18-xen.hg/drivers/xen/blktap/blktap.c
> @@ -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;
> Â Â Â Â Â Â Â Â Â Â Â Â}
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blktap/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/blktap/interface.c
> @@ -59,25 +59,23 @@ blkif_t *tap_alloc_blkif(domid_t domid)
> Â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)
> --- linux-2.6.18-xen.hg.orig/drivers/xen/blktap2/device.c
> +++ linux-2.6.18-xen.hg/drivers/xen/blktap2/device.c
> @@ -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++;
> Â Â Â Â Â Â Â Â}
>
> - Â Â Â Â Â Â Â request->handles[i].user = table->grants[grant].handle;
> - Â Â Â Â Â Â Â grant++;
> -
> - Â Â Â done:
> Â Â Â Â Â Â Â Â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) {
> --- linux-2.6.18-xen.hg.orig/drivers/xen/core/gnttab.c
> +++ linux-2.6.18-xen.hg/drivers/xen/core/gnttab.c
> @@ -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);
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/gntdev/gntdev.c
> +++ linux-2.6.18-xen.hg/drivers/xen/gntdev/gntdev.c
> @@ -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);
>
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/netback/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/netback/interface.c
> @@ -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);
> + Â Â Â gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
>
> - Â Â Â if (op.status) {
> + Â Â Â 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;
> --- linux-2.6.18-xen.hg.orig/drivers/xen/netback/netback.c
> +++ linux-2.6.18-xen.hg/drivers/xen/netback/netback.c
> @@ -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;
> Â Â Â Â}
> @@ -1107,7 +1083,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;
> @@ -1128,12 +1104,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;
> Â Â Â Â Â Â Â Â}
> @@ -1145,7 +1121,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. */
> --- linux-2.6.18-xen.hg.orig/drivers/xen/scsiback/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/scsiback/interface.c
> @@ -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)
> --- linux-2.6.18-xen.hg.orig/drivers/xen/scsiback/scsiback.c
> +++ linux-2.6.18-xen.hg/drivers/xen/scsiback/scsiback.c
> @@ -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;
> --- linux-2.6.18-xen.hg.orig/drivers/xen/sfc_netutil/accel_util.c
> +++ linux-2.6.18-xen.hg/drivers/xen/sfc_netutil/accel_util.c
> @@ -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;
> + Â Â Â Â Â Â Â ret = 0;
> Â Â Â Â}
>
> - Â Â Â return op.status;
> + Â Â Â 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 @@ EXPORT_SYMBOL(net_accel_unmap_grants_con
> Â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);
>
> --- linux-2.6.18-xen.hg.orig/drivers/xen/tpmback/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/tpmback/interface.c
> @@ -81,25 +81,23 @@ tpmif_t *tpmif_find(domid_t domid, struc
> Â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)
> --- linux-2.6.18-xen.hg.orig/drivers/xen/tpmback/tpmback.c
> +++ linux-2.6.18-xen.hg/drivers/xen/tpmback/tpmback.c
> @@ -257,20 +257,15 @@ 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);
> + Â Â Â Â Â Â Â gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, 
> &map_op);
>
> - Â Â Â Â Â Â Â handle = map_op.handle;
> -
> - Â Â Â Â Â Â Â if (map_op.status) {
> + Â Â Â Â Â Â Â 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);
>
> Â Â Â Â Â Â Â Âif (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
> @@ -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);
> + Â Â Â Â Â Â Â gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, 
> &map_op);
>
> - Â Â Â Â Â Â Â if (map_op.status) {
> + Â Â Â Â Â Â Â if (map_op.status != GNTST_okay) {
> Â Â Â Â Â Â Â Â Â Â Â ÂDPRINTK(" Grant table operation failure !\n");
> Â Â Â Â Â Â Â Â Â Â Â Âreturn -EFAULT;
> Â Â Â Â Â Â Â Â}
> --- linux-2.6.18-xen.hg.orig/drivers/xen/usbback/interface.c
> +++ linux-2.6.18-xen.hg/drivers/xen/usbback/interface.c
> @@ -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);
>
> + Â Â Â gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
>
> - Â Â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;
> + Â Â Â 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);
> + Â Â Â gnttab_check_GNTST_eagain_do_while(GNTTABOP_map_grant_ref, &op);
>
> - Â Â Â if (op.status) {
> + Â Â Â 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;
> --- linux-2.6.18-xen.hg.orig/drivers/xen/usbback/usbback.c
> +++ linux-2.6.18-xen.hg/drivers/xen/usbback/usbback.c
> @@ -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;
> --- linux-2.6.18-xen.hg.orig/drivers/xen/xenbus/xenbus_backend_client.c
> +++ linux-2.6.18-xen.hg/drivers/xen/xenbus/xenbus_backend_client.c
> @@ -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);
>
> --- linux-2.6.18-xen.hg.orig/include/xen/gnttab.h
> +++ linux-2.6.18-xen.hg/include/xen/gnttab.h
> @@ -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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.