]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
blk-mq: don't wait in blk_mq_queue_enter() if __GFP_WAIT isn't set
authorKeith Busch <keith.busch@intel.com>
Thu, 12 Mar 2015 03:56:39 +0000 (23:56 -0400)
committerJens Axboe <axboe@fb.com>
Fri, 13 Mar 2015 14:30:55 +0000 (08:30 -0600)
Return -EBUSY if we're unable to enter a queue immediately when
allocating a blk-mq request without __GFP_WAIT.

Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-mq.c

index 06614ce0f475265de9f5df36842ed1b4a96635dd..59fa23935a0f10e19e13cea5b7086fbf9f85c170 100644 (file)
@@ -77,7 +77,7 @@ static void blk_mq_hctx_clear_pending(struct blk_mq_hw_ctx *hctx,
        clear_bit(CTX_TO_BIT(hctx, ctx), &bm->word);
 }
 
-static int blk_mq_queue_enter(struct request_queue *q)
+static int blk_mq_queue_enter(struct request_queue *q, gfp_t gfp)
 {
        while (true) {
                int ret;
@@ -85,6 +85,9 @@ static int blk_mq_queue_enter(struct request_queue *q)
                if (percpu_ref_tryget_live(&q->mq_usage_counter))
                        return 0;
 
+               if (!(gfp & __GFP_WAIT))
+                       return -EBUSY;
+
                ret = wait_event_interruptible(q->mq_freeze_wq,
                                !q->mq_freeze_depth || blk_queue_dying(q));
                if (blk_queue_dying(q))
@@ -256,7 +259,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp,
        struct blk_mq_alloc_data alloc_data;
        int ret;
 
-       ret = blk_mq_queue_enter(q);
+       ret = blk_mq_queue_enter(q, gfp);
        if (ret)
                return ERR_PTR(ret);
 
@@ -1186,7 +1189,7 @@ static struct request *blk_mq_map_request(struct request_queue *q,
        int rw = bio_data_dir(bio);
        struct blk_mq_alloc_data alloc_data;
 
-       if (unlikely(blk_mq_queue_enter(q))) {
+       if (unlikely(blk_mq_queue_enter(q, GFP_KERNEL))) {
                bio_endio(bio, -EIO);
                return NULL;
        }