blk-mq: change gfp flags to GFP_NOIO in blk_mq_realloc_hw_ctxs
authorJianchao Wang <jianchao.w.wang@oracle.com>
Fri, 12 Oct 2018 10:07:26 +0000 (18:07 +0800)
committerJens Axboe <axboe@kernel.dk>
Sat, 13 Oct 2018 21:42:01 +0000 (15:42 -0600)
blk_mq_realloc_hw_ctxs could be invoked during update hw queues.
At the momemt, IO is blocked. Change the gfp flags from GFP_KERNEL
to GFP_NOIO to avoid forever hang during memory allocation in
blk_mq_realloc_hw_ctxs.

Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-core.c
block/blk-flush.c
block/blk-mq.c
block/blk.h

index f12d2b65e5a541ec30c55ca3e52aef64150672c3..c5539eed02024c865cb0c0a70363d27caf497c5c 100644 (file)
@@ -1163,7 +1163,7 @@ int blk_init_allocated_queue(struct request_queue *q)
 {
        WARN_ON_ONCE(q->mq_ops);
 
-       q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size);
+       q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size, GFP_KERNEL);
        if (!q->fq)
                return -ENOMEM;
 
index ce41f666de3e1d068e78698349c1629d7e118bc8..8b44b86779daa83e96cf9408532933f75d23ea51 100644 (file)
@@ -566,12 +566,12 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
 EXPORT_SYMBOL(blkdev_issue_flush);
 
 struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q,
-               int node, int cmd_size)
+               int node, int cmd_size, gfp_t flags)
 {
        struct blk_flush_queue *fq;
        int rq_sz = sizeof(struct request);
 
-       fq = kzalloc_node(sizeof(*fq), GFP_KERNEL, node);
+       fq = kzalloc_node(sizeof(*fq), flags, node);
        if (!fq)
                goto fail;
 
@@ -579,7 +579,7 @@ struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q,
                spin_lock_init(&fq->mq_flush_lock);
 
        rq_sz = round_up(rq_sz + cmd_size, cache_line_size());
-       fq->flush_rq = kzalloc_node(rq_sz, GFP_KERNEL, node);
+       fq->flush_rq = kzalloc_node(rq_sz, flags, node);
        if (!fq->flush_rq)
                goto fail_rq;
 
index 99a72c6507289bc83f379ad2510db6a2fe2e710b..6b734461fd39589577bf6ba360e6882621a1a6fe 100644 (file)
@@ -2210,12 +2210,12 @@ static int blk_mq_init_hctx(struct request_queue *q,
         * runtime
         */
        hctx->ctxs = kmalloc_array_node(nr_cpu_ids, sizeof(void *),
-                                       GFP_KERNEL, node);
+                       GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, node);
        if (!hctx->ctxs)
                goto unregister_cpu_notifier;
 
-       if (sbitmap_init_node(&hctx->ctx_map, nr_cpu_ids, ilog2(8), GFP_KERNEL,
-                             node))
+       if (sbitmap_init_node(&hctx->ctx_map, nr_cpu_ids, ilog2(8),
+                               GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, node))
                goto free_ctxs;
 
        hctx->nr_ctx = 0;
@@ -2228,7 +2228,8 @@ static int blk_mq_init_hctx(struct request_queue *q,
            set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
                goto free_bitmap;
 
-       hctx->fq = blk_alloc_flush_queue(q, hctx->numa_node, set->cmd_size);
+       hctx->fq = blk_alloc_flush_queue(q, hctx->numa_node, set->cmd_size,
+                       GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY);
        if (!hctx->fq)
                goto exit_hctx;
 
@@ -2536,12 +2537,14 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
 
                node = blk_mq_hw_queue_to_node(q->mq_map, i);
                hctxs[i] = kzalloc_node(blk_mq_hw_ctx_size(set),
-                                       GFP_KERNEL, node);
+                               GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY,
+                               node);
                if (!hctxs[i])
                        break;
 
-               if (!zalloc_cpumask_var_node(&hctxs[i]->cpumask, GFP_KERNEL,
-                                               node)) {
+               if (!zalloc_cpumask_var_node(&hctxs[i]->cpumask,
+                                       GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY,
+                                       node)) {
                        kfree(hctxs[i]);
                        hctxs[i] = NULL;
                        break;
index 58c030f727e90c68b2f2766ea7a20241174ce066..3d2aecba96a46c7b28dd1207a0874ab2e27520ee 100644 (file)
@@ -125,7 +125,7 @@ static inline void __blk_get_queue(struct request_queue *q)
 }
 
 struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q,
-               int node, int cmd_size);
+               int node, int cmd_size, gfp_t flags);
 void blk_free_flush_queue(struct blk_flush_queue *q);
 
 int blk_init_rl(struct request_list *rl, struct request_queue *q,