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
|