Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / block / blk-tag.c
index c260f7c..4af6f5c 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "blk.h"
 
@@ -281,16 +282,9 @@ EXPORT_SYMBOL(blk_queue_resize_tags);
 void blk_queue_end_tag(struct request_queue *q, struct request *rq)
 {
        struct blk_queue_tag *bqt = q->queue_tags;
-       int tag = rq->tag;
+       unsigned tag = rq->tag; /* negative tags invalid */
 
-       BUG_ON(tag == -1);
-
-       if (unlikely(tag >= bqt->real_max_depth))
-               /*
-                * This can happen after tag depth has been reduced.
-                * FIXME: how about a warning or info message here?
-                */
-               return;
+       BUG_ON(tag >= bqt->real_max_depth);
 
        list_del_init(&rq->queuelist);
        rq->cmd_flags &= ~REQ_QUEUED;
@@ -336,7 +330,7 @@ EXPORT_SYMBOL(blk_queue_end_tag);
 int blk_queue_start_tag(struct request_queue *q, struct request *rq)
 {
        struct blk_queue_tag *bqt = q->queue_tags;
-       unsigned max_depth, offset;
+       unsigned max_depth;
        int tag;
 
        if (unlikely((rq->cmd_flags & REQ_QUEUED))) {
@@ -355,13 +349,16 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
         * to starve sync IO on behalf of flooding async IO.
         */
        max_depth = bqt->max_depth;
-       if (rq_is_sync(rq))
-               offset = 0;
-       else
-               offset = max_depth >> 2;
+       if (!rq_is_sync(rq) && max_depth > 1) {
+               max_depth -= 2;
+               if (!max_depth)
+                       max_depth = 1;
+               if (q->in_flight[BLK_RW_ASYNC] > max_depth)
+                       return 1;
+       }
 
        do {
-               tag = find_next_zero_bit(bqt->tag_map, max_depth, offset);
+               tag = find_first_zero_bit(bqt->tag_map, max_depth);
                if (tag >= max_depth)
                        return 1;