]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
blkback/blktap: Check for kthread_should_stop() in inner loop,
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 22 Jan 2008 11:33:40 +0000 (11:33 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 22 Jan 2008 11:33:40 +0000 (11:33 +0000)
mdelaay() should be msleep(), and these changes belong in blktap as
well as blkback.
Based on comments and patches from Jan Beulich and Steven Smith.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
linux-2.6.18-xen changeset:   392:7070d34f251c3e0c411022a5d365aea9804114a7
linux-2.6.18-xen date:        Mon Jan 21 11:43:31 2008 +0000

blkback: Request-processing loop is unbounded and hence requires a
yield point. Also, bad request type is a good cause to sleep for a
short while as the frontend has probably gone mad.

Patch by Steven Smith <steven.smith@eu.citrix.com>

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
linux-2.6.18-xen changeset:   391:77f831cbb91ddca3a7539fa9197d4abc2d2bfcf9
linux-2.6.18-xen date:        Fri Jan 18 16:52:25 2008 +0000

linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c

index d8bce45956d75d33d6a7be1fd19187c0ff31499b..7e704256297f750933b583a1ee5bbd6f6ba93ddc 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
 #include <linux/list.h>
+#include <linux/delay.h>
 #include <xen/balloon.h>
 #include <asm/hypervisor.h>
 #include "common.h"
@@ -311,7 +312,7 @@ static int do_block_io_op(blkif_t *blkif)
        rp = blk_rings->common.sring->req_prod;
        rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-       while ((rc != rp)) {
+       while (rc != rp) {
 
                if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
                        break;
@@ -323,6 +324,11 @@ static int do_block_io_op(blkif_t *blkif)
                        break;
                }
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                switch (blkif->blk_protocol) {
                case BLKIF_PROTOCOL_NATIVE:
                        memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc), sizeof(req));
@@ -351,6 +357,9 @@ static int do_block_io_op(blkif_t *blkif)
                        dispatch_rw_block_io(blkif, &req, pending_req);
                        break;
                default:
+                       /* A good sign something is wrong: sleep for a while to
+                        * avoid excessive CPU consumption by a bad guest. */
+                       msleep(1);
                        DPRINTK("error: unknown block io operation [%d]\n",
                                req.operation);
                        make_response(blkif, req.id, req.operation,
@@ -358,7 +367,11 @@ static int do_block_io_op(blkif_t *blkif)
                        free_req(pending_req);
                        break;
                }
+
+               /* Yield point for this unbounded loop. */
+               cond_resched();
        }
+
        return more_to_do;
 }
 
@@ -509,6 +522,7 @@ static void dispatch_rw_block_io(blkif_t *blkif,
  fail_response:
        make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
        free_req(pending_req);
+       msleep(1); /* back off a bit */
 } 
 
 
index 5f3809534f59b2f44ccb86ba288f81049f5c1ebb..24f7bfcec441558567e9b4d3594ec1295d90111b 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/major.h>
 #include <linux/gfp.h>
 #include <linux/poll.h>
+#include <linux/delay.h>
 #include <asm/tlbflush.h>
 
 #define MAX_TAP_DEV 256     /*the maximum number of tapdisk ring devices    */
@@ -1242,6 +1243,11 @@ static int do_block_io_op(blkif_t *blkif)
                        break;
                }
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                switch (blkif->blk_protocol) {
                case BLKIF_PROTOCOL_NATIVE:
                        memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc),
@@ -1270,6 +1276,9 @@ static int do_block_io_op(blkif_t *blkif)
                        break;
 
                default:
+                       /* A good sign something is wrong: sleep for a while to
+                        * avoid excessive CPU consumption by a bad guest. */
+                       msleep(1);
                        WPRINTK("unknown operation [%d]\n",
                                req.operation);
                        make_response(blkif, req.id, req.operation,
@@ -1277,6 +1286,9 @@ static int do_block_io_op(blkif_t *blkif)
                        free_req(pending_req);
                        break;
                }
+
+               /* Yield point for this unbounded loop. */
+               cond_resched();
        }
                
        blktap_kick_user(blkif->dev_num);
@@ -1503,7 +1515,8 @@ static void dispatch_rw_block_io(blkif_t *blkif,
  fail_response:
        make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
        free_req(pending_req);
-} 
+       msleep(1); /* back off a bit */
+}