cfq-iosched: make nonrot check logic consistent
[safe/jmp/linux-2.6] / block / blk-tag.c
index 8a99688..6b0f52c 100644 (file)
@@ -158,7 +158,6 @@ fail:
 /**
  * blk_init_tags - initialize the tag info for an external tag map
  * @depth:     the maximum queue depth supported
- * @tags: the tag to use
  **/
 struct blk_queue_tag *blk_init_tags(int depth)
 {
@@ -337,6 +336,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;
        int tag;
 
        if (unlikely((rq->cmd_flags & REQ_QUEUED))) {
@@ -350,10 +350,22 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
        /*
         * Protect against shared tag maps, as we may not have exclusive
         * access to the tag map.
+        *
+        * We reserve a few tags just for sync IO, since we don't want
+        * to starve sync IO on behalf of flooding async IO.
         */
+       max_depth = bqt->max_depth;
+       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_first_zero_bit(bqt->tag_map, bqt->max_depth);
-               if (tag >= bqt->max_depth)
+               tag = find_first_zero_bit(bqt->tag_map, max_depth);
+               if (tag >= max_depth)
                        return 1;
 
        } while (test_and_set_bit_lock(tag, bqt->tag_map));
@@ -365,7 +377,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
        rq->cmd_flags |= REQ_QUEUED;
        rq->tag = tag;
        bqt->tag_index[tag] = rq;
-       blkdev_dequeue_request(rq);
+       blk_start_request(rq);
        list_add(&rq->queuelist, &q->tag_busy_list);
        return 0;
 }