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