Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / block / blk-mq.c
index 495f508..65d3a63 100644 (file)
@@ -525,7 +525,7 @@ void blk_mq_free_request(struct request *rq)
                __blk_mq_dec_active_requests(hctx);
 
        if (unlikely(laptop_mode && !blk_rq_is_passthrough(rq)))
-               laptop_io_completion(q->backing_dev_info);
+               laptop_io_completion(q->disk->bdi);
 
        rq_qos_done(q, rq);
 
@@ -606,7 +606,7 @@ static inline bool blk_mq_complete_need_ipi(struct request *rq)
         * This is probably worse than completing the request on a different
         * cache domain.
         */
-       if (force_irqthreads)
+       if (force_irqthreads())
                return false;
 
        /* same CPU or cache domain?  Complete locally */
@@ -911,7 +911,7 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
 
 void blk_mq_put_rq_ref(struct request *rq)
 {
-       if (is_flush_rq(rq, rq->mq_hctx))
+       if (is_flush_rq(rq))
                rq->end_io(rq, 0);
        else if (refcount_dec_and_test(&rq->ref))
                __blk_mq_free_request(rq);
@@ -923,34 +923,14 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
        unsigned long *next = priv;
 
        /*
-        * Just do a quick check if it is expired before locking the request in
-        * so we're not unnecessarilly synchronizing across CPUs.
-        */
-       if (!blk_mq_req_expired(rq, next))
-               return true;
-
-       /*
-        * We have reason to believe the request may be expired. Take a
-        * reference on the request to lock this request lifetime into its
-        * currently allocated context to prevent it from being reallocated in
-        * the event the completion by-passes this timeout handler.
-        *
-        * If the reference was already released, then the driver beat the
-        * timeout handler to posting a natural completion.
-        */
-       if (!refcount_inc_not_zero(&rq->ref))
-               return true;
-
-       /*
-        * The request is now locked and cannot be reallocated underneath the
-        * timeout handler's processing. Re-verify this exact request is truly
-        * expired; if it is not expired, then the request was completed and
-        * reallocated as a new request.
+        * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot
+        * be reallocated underneath the timeout handler's processing, then
+        * the expire check is reliable. If the request is not expired, then
+        * it was completed and reallocated as a new request after returning
+        * from blk_mq_check_expired().
         */
        if (blk_mq_req_expired(rq, next))
                blk_mq_rq_timed_out(rq, reserved);
-
-       blk_mq_put_rq_ref(rq);
        return true;
 }
 
@@ -2994,10 +2974,12 @@ static void queue_set_hctx_shared(struct request_queue *q, bool shared)
        int i;
 
        queue_for_each_hw_ctx(q, hctx, i) {
-               if (shared)
+               if (shared) {
                        hctx->flags |= BLK_MQ_F_TAG_QUEUE_SHARED;
-               else
+               } else {
+                       blk_mq_tag_idle(hctx);
                        hctx->flags &= ~BLK_MQ_F_TAG_QUEUE_SHARED;
+               }
        }
 }
 
@@ -3133,7 +3115,8 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
 }
 EXPORT_SYMBOL(blk_mq_init_queue);
 
-struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata)
+struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata,
+               struct lock_class_key *lkclass)
 {
        struct request_queue *q;
        struct gendisk *disk;
@@ -3142,12 +3125,11 @@ struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata)
        if (IS_ERR(q))
                return ERR_CAST(q);
 
-       disk = __alloc_disk_node(0, set->numa_node);
+       disk = __alloc_disk_node(q, set->numa_node, lkclass);
        if (!disk) {
                blk_cleanup_queue(q);
                return ERR_PTR(-ENOMEM);
        }
-       disk->queue = q;
        return disk;
 }
 EXPORT_SYMBOL(__blk_mq_alloc_disk);