Firstly the hctx->tags have to be set as NULL if it is to be disabled
no matter if set->tags[i] is NULL or not in blk_mq_map_swqueue() because
shared tags can be freed already from another request queue.

The same situation has to be considered in blk_mq_hctx_cpu_online()
too.

Cc: <[email protected]>
Reported-by: Dongsu Park <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
---
 block/blk-mq.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 6804028..9da05b3 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1580,15 +1580,20 @@ static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx 
*hctx, int cpu)
 {
        struct request_queue *q = hctx->queue;
        struct blk_mq_tag_set *set = q->tag_set;
+       struct blk_mq_tags      *tags = set->tags[hctx->queue_num];
 
-       if (set->tags[hctx->queue_num])
+       /* tags can be shared by more than one queues */
+       if (hctx->tags)
                return NOTIFY_OK;
 
-       set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num);
-       if (!set->tags[hctx->queue_num])
-               return NOTIFY_STOP;
+       if (!tags) {
+               tags = blk_mq_init_rq_map(set, hctx->queue_num);
+               if (!tags)
+                       return NOTIFY_STOP;
+               set->tags[hctx->queue_num] = tags;
+       }
 
-       hctx->tags = set->tags[hctx->queue_num];
+       hctx->tags = tags;
        return NOTIFY_OK;
 }
 
@@ -1813,8 +1818,8 @@ static void blk_mq_map_swqueue(struct request_queue *q)
                        if (set->tags[i]) {
                                blk_mq_free_rq_map(set, set->tags[i], i);
                                set->tags[i] = NULL;
-                               hctx->tags = NULL;
                        }
+                       hctx->tags = NULL;
                        continue;
                }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to