]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - block/blk-mq.c
blk-mq: Introduce blk_mq_hctx_stopped()
[mirror_ubuntu-bionic-kernel.git] / block / blk-mq.c
index ddc2eed6477146320073b061a61e15ebe4d587eb..2864e191cc86c39a02b7783860f54df0e159490f 100644 (file)
@@ -139,17 +139,15 @@ bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
 EXPORT_SYMBOL(blk_mq_can_queue);
 
 static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
-                              struct request *rq, int op,
-                              unsigned int op_flags)
+                              struct request *rq, unsigned int op)
 {
-       if (blk_queue_io_stat(q))
-               op_flags |= REQ_IO_STAT;
-
        INIT_LIST_HEAD(&rq->queuelist);
        /* csd/requeue_work/fifo_time is initialized before use */
        rq->q = q;
        rq->mq_ctx = ctx;
-       req_set_op_attrs(rq, op, op_flags);
+       rq->cmd_flags = op;
+       if (blk_queue_io_stat(q))
+               rq->rq_flags |= RQF_IO_STAT;
        /* do not touch atomic flags, it needs atomic ops against the timer */
        rq->cpu = -1;
        INIT_HLIST_NODE(&rq->hash);
@@ -184,11 +182,11 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
        rq->end_io_data = NULL;
        rq->next_rq = NULL;
 
-       ctx->rq_dispatched[rw_is_sync(op, op_flags)]++;
+       ctx->rq_dispatched[op_is_sync(op)]++;
 }
 
 static struct request *
-__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int op, int op_flags)
+__blk_mq_alloc_request(struct blk_mq_alloc_data *data, unsigned int op)
 {
        struct request *rq;
        unsigned int tag;
@@ -198,12 +196,12 @@ __blk_mq_alloc_request(struct blk_mq_alloc_data *data, int op, int op_flags)
                rq = data->hctx->tags->rqs[tag];
 
                if (blk_mq_tag_busy(data->hctx)) {
-                       rq->cmd_flags = REQ_MQ_INFLIGHT;
+                       rq->rq_flags = RQF_MQ_INFLIGHT;
                        atomic_inc(&data->hctx->nr_active);
                }
 
                rq->tag = tag;
-               blk_mq_rq_ctx_init(data->q, data->ctx, rq, op, op_flags);
+               blk_mq_rq_ctx_init(data->q, data->ctx, rq, op);
                return rq;
        }
 
@@ -226,7 +224,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
        ctx = blk_mq_get_ctx(q);
        hctx = blk_mq_map_queue(q, ctx->cpu);
        blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
-       rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
+       rq = __blk_mq_alloc_request(&alloc_data, rw);
        blk_mq_put_ctx(ctx);
 
        if (!rq) {
@@ -278,7 +276,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int rw,
        ctx = __blk_mq_get_ctx(q, cpumask_first(hctx->cpumask));
 
        blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
-       rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
+       rq = __blk_mq_alloc_request(&alloc_data, rw);
        if (!rq) {
                ret = -EWOULDBLOCK;
                goto out_queue_exit;
@@ -298,9 +296,9 @@ static void __blk_mq_free_request(struct blk_mq_hw_ctx *hctx,
        const int tag = rq->tag;
        struct request_queue *q = rq->q;
 
-       if (rq->cmd_flags & REQ_MQ_INFLIGHT)
+       if (rq->rq_flags & RQF_MQ_INFLIGHT)
                atomic_dec(&hctx->nr_active);
-       rq->cmd_flags = 0;
+       rq->rq_flags = 0;
 
        clear_bit(REQ_ATOM_STARTED, &rq->atomic_flags);
        blk_mq_put_tag(hctx, ctx, tag);
@@ -489,10 +487,10 @@ static void blk_mq_requeue_work(struct work_struct *work)
        spin_unlock_irqrestore(&q->requeue_lock, flags);
 
        list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
-               if (!(rq->cmd_flags & REQ_SOFTBARRIER))
+               if (!(rq->rq_flags & RQF_SOFTBARRIER))
                        continue;
 
-               rq->cmd_flags &= ~REQ_SOFTBARRIER;
+               rq->rq_flags &= ~RQF_SOFTBARRIER;
                list_del_init(&rq->queuelist);
                blk_mq_insert_request(rq, true, false, false);
        }
@@ -519,11 +517,11 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head)
         * We abuse this flag that is otherwise used by the I/O scheduler to
         * request head insertation from the workqueue.
         */
-       BUG_ON(rq->cmd_flags & REQ_SOFTBARRIER);
+       BUG_ON(rq->rq_flags & RQF_SOFTBARRIER);
 
        spin_lock_irqsave(&q->requeue_lock, flags);
        if (at_head) {
-               rq->cmd_flags |= REQ_SOFTBARRIER;
+               rq->rq_flags |= RQF_SOFTBARRIER;
                list_add(&rq->queuelist, &q->requeue_list);
        } else {
                list_add_tail(&rq->queuelist, &q->requeue_list);
@@ -787,7 +785,7 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
        struct list_head *dptr;
        int queued;
 
-       if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
+       if (unlikely(blk_mq_hctx_stopped(hctx)))
                return;
 
        WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
@@ -912,8 +910,8 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx)
 
 void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 {
-       if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state) ||
-           !blk_mq_hw_queue_mapped(hctx)))
+       if (unlikely(blk_mq_hctx_stopped(hctx) ||
+                    !blk_mq_hw_queue_mapped(hctx)))
                return;
 
        if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) {
@@ -938,7 +936,7 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async)
        queue_for_each_hw_ctx(q, hctx, i) {
                if ((!blk_mq_hctx_has_pending(hctx) &&
                    list_empty_careful(&hctx->dispatch)) ||
-                   test_bit(BLK_MQ_S_STOPPED, &hctx->state))
+                   blk_mq_hctx_stopped(hctx))
                        continue;
 
                blk_mq_run_hw_queue(hctx, async);
@@ -988,7 +986,7 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async)
        int i;
 
        queue_for_each_hw_ctx(q, hctx, i) {
-               if (!test_bit(BLK_MQ_S_STOPPED, &hctx->state))
+               if (!blk_mq_hctx_stopped(hctx))
                        continue;
 
                clear_bit(BLK_MQ_S_STOPPED, &hctx->state);
@@ -1190,36 +1188,23 @@ insert_rq:
        }
 }
 
-struct blk_map_ctx {
-       struct blk_mq_hw_ctx *hctx;
-       struct blk_mq_ctx *ctx;
-};
-
 static struct request *blk_mq_map_request(struct request_queue *q,
                                          struct bio *bio,
-                                         struct blk_map_ctx *data)
+                                         struct blk_mq_alloc_data *data)
 {
        struct blk_mq_hw_ctx *hctx;
        struct blk_mq_ctx *ctx;
        struct request *rq;
-       int op = bio_data_dir(bio);
-       int op_flags = 0;
-       struct blk_mq_alloc_data alloc_data;
 
        blk_queue_enter_live(q);
        ctx = blk_mq_get_ctx(q);
        hctx = blk_mq_map_queue(q, ctx->cpu);
 
-       if (rw_is_sync(bio_op(bio), bio->bi_opf))
-               op_flags |= REQ_SYNC;
+       trace_block_getrq(q, bio, bio->bi_opf);
+       blk_mq_set_alloc_data(data, q, 0, ctx, hctx);
+       rq = __blk_mq_alloc_request(data, bio->bi_opf);
 
-       trace_block_getrq(q, bio, op);
-       blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
-       rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
-
-       hctx->queued++;
-       data->hctx = hctx;
-       data->ctx = ctx;
+       data->hctx->queued++;
        return rq;
 }
 
@@ -1265,9 +1250,9 @@ static int blk_mq_direct_issue_request(struct request *rq, blk_qc_t *cookie)
  */
 static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
 {
-       const int is_sync = rw_is_sync(bio_op(bio), bio->bi_opf);
+       const int is_sync = op_is_sync(bio->bi_opf);
        const int is_flush_fua = bio->bi_opf & (REQ_PREFLUSH | REQ_FUA);
-       struct blk_map_ctx data;
+       struct blk_mq_alloc_data data;
        struct request *rq;
        unsigned int request_count = 0;
        struct blk_plug *plug;
@@ -1332,9 +1317,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
                blk_mq_put_ctx(data.ctx);
                if (!old_rq)
                        goto done;
-               if (!blk_mq_direct_issue_request(old_rq, &cookie))
-                       goto done;
-               blk_mq_insert_request(old_rq, false, true, true);
+               if (blk_mq_hctx_stopped(data.hctx) ||
+                   blk_mq_direct_issue_request(old_rq, &cookie) != 0)
+                       blk_mq_insert_request(old_rq, false, true, true);
                goto done;
        }
 
@@ -1359,11 +1344,11 @@ done:
  */
 static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
 {
-       const int is_sync = rw_is_sync(bio_op(bio), bio->bi_opf);
+       const int is_sync = op_is_sync(bio->bi_opf);
        const int is_flush_fua = bio->bi_opf & (REQ_PREFLUSH | REQ_FUA);
        struct blk_plug *plug;
        unsigned int request_count = 0;
-       struct blk_map_ctx data;
+       struct blk_mq_alloc_data data;
        struct request *rq;
        blk_qc_t cookie;