WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] Fixes to block backend to handle -EAG

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Fixes to block backend to handle -EAGAIN grant table errors properly.
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Dec 2009 22:41:41 -0800
Delivery-date: Wed, 16 Dec 2009 22:45:18 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031870 0
# Node ID df70d482d0f43fbd6f5e55a006350e93e26ed9a5
# Parent  981db8d78913016a0dbfa041e106b3404b5f5791
Fixes to block backend to handle -EAGAIN grant table errors properly.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 drivers/xen/blkback/blkback.c   |   53 ++++++++++++++++++++++++++++++++--------
 drivers/xen/blkback/common.h    |    2 +
 drivers/xen/blkback/interface.c |    8 ++++--
 3 files changed, 51 insertions(+), 12 deletions(-)

diff -r 981db8d78913 -r df70d482d0f4 drivers/xen/blkback/blkback.c
--- a/drivers/xen/blkback/blkback.c     Thu Dec 17 06:37:49 2009 +0000
+++ b/drivers/xen/blkback/blkback.c     Thu Dec 17 06:37:50 2009 +0000
@@ -107,7 +107,7 @@ static inline unsigned long vaddr(pendin
 
 
 static int do_block_io_op(blkif_t *blkif);
-static void dispatch_rw_block_io(blkif_t *blkif,
+static int 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,
@@ -309,13 +309,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;
+       int more_to_do = 0, ret;
 
        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) {
+       while ((rc != rp) || (blkif->is_suspended_req)) {
 
                if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
                        break;
@@ -332,6 +332,14 @@ 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));
@@ -350,17 +358,19 @@ 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++;
-                       dispatch_rw_block_io(blkif, &req, pending_req);
+                       ret = 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++;
-                       dispatch_rw_block_io(blkif, &req, pending_req);
+                       ret = dispatch_rw_block_io(blkif, &req, pending_req);
                        break;
                default:
                        /* A good sign something is wrong: sleep for a while to
@@ -373,6 +383,17 @@ static int do_block_io_op(blkif_t *blkif
                        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();
@@ -381,7 +402,7 @@ static int do_block_io_op(blkif_t *blkif
        return more_to_do;
 }
 
-static void dispatch_rw_block_io(blkif_t *blkif,
+static int dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req)
 {
@@ -450,11 +471,15 @@ static void 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)) {
                        DPRINTK("invalid buffer -- could not remap it\n");
                        map[i].handle = BLKBACK_INVALID_HANDLE;
-                       ret |= 1;
+                       ret |= GENERAL_ERR;
+            if(map[i].status == GNTST_eagain)
+                           ret |= EAGAIN_ERR;
                } else {
                        blkback_pagemap_set(vaddr_pagenr(pending_req, i),
                                            pending_page(pending_req, i),
@@ -473,6 +498,14 @@ static void dispatch_rw_block_io(blkif_t
                seg[i].buf  = map[i].dev_bus_addr | 
                        (req->seg[i].first_sect << 9);
        }
+
+    /* If any of grant maps failed with GNTST_eagain, suspend and retry later 
*/
+    if(ret & EAGAIN_ERR)
+    {
+        fast_flush_area(pending_req);
+        free_req(pending_req);
+        return -EAGAIN;
+    }
 
        if (ret)
                goto fail_flush;
@@ -539,7 +572,7 @@ static void dispatch_rw_block_io(blkif_t
        else if (operation == WRITE || operation == WRITE_BARRIER)
                blkif->st_wr_sect += preq.nr_sects;
 
-       return;
+       return 0;
 
  fail_flush:
        fast_flush_area(pending_req);
@@ -547,7 +580,7 @@ static void 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;
+       return 0;
 
  fail_put_bio:
        __end_block_io_op(pending_req, -EINVAL);
@@ -555,7 +588,7 @@ static void dispatch_rw_block_io(blkif_t
                bio_put(bio);
        unplug_queue(blkif);
        msleep(1); /* back off a bit */
-       return;
+       return 0;
 }
 
 
diff -r 981db8d78913 -r df70d482d0f4 drivers/xen/blkback/common.h
--- a/drivers/xen/blkback/common.h      Thu Dec 17 06:37:49 2009 +0000
+++ b/drivers/xen/blkback/common.h      Thu Dec 17 06:37:50 2009 +0000
@@ -82,6 +82,8 @@ typedef struct blkif_st {
        struct task_struct  *xenblkd;
        unsigned int        waiting_reqs;
        request_queue_t     *plug;
+    int                 is_suspended_req;
+    blkif_request_t     suspended_req;
 
        /* statistics */
        unsigned long       st_print;
diff -r 981db8d78913 -r df70d482d0f4 drivers/xen/blkback/interface.c
--- a/drivers/xen/blkback/interface.c   Thu Dec 17 06:37:49 2009 +0000
+++ b/drivers/xen/blkback/interface.c   Thu Dec 17 06:37:50 2009 +0000
@@ -33,6 +33,7 @@
 #include "common.h"
 #include <xen/evtchn.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
 
 static kmem_cache_t *blkif_cachep;
 
@@ -62,8 +63,11 @@ static int map_frontend_page(blkif_t *bl
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
+    do {
+           if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+                   BUG();
+        msleep(100);
+    } while(op.status == GNTST_eagain);
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Fixes to block backend to handle -EAGAIN grant table errors properly., Xen patchbot-linux-2.6.18-xen <=