blk-mq: Introduce blk_mq_reinit_tagset
authorSagi Grimberg <sagi@grimberg.me>
Wed, 6 Jul 2016 12:55:48 +0000 (21:55 +0900)
committerJens Axboe <axboe@fb.com>
Fri, 8 Jul 2016 14:38:49 +0000 (08:38 -0600)
The new nvme-rdma driver will need to reinitialize all the tags as part of
the error recovery procedure (realloc the tag memory region). Add a helper
in blk-mq for it that can iterate over all requests in a tagset to make
this easier.

Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Tested-by: Ming Lin <ming.l@ssi.samsung.com>
Reviewed-by: Stephen Bates <Stephen.Bates@pmcs.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-mq-tag.c
include/linux/blk-mq.h

index 56a0c37a3d06e0e4037c1cda55c0c6d1c6a98f21..729bac3a673b7a89577669c1a65e70fc60309d5a 100644 (file)
@@ -485,6 +485,32 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
 }
 EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
 
+int blk_mq_reinit_tagset(struct blk_mq_tag_set *set)
+{
+       int i, j, ret = 0;
+
+       if (!set->ops->reinit_request)
+               goto out;
+
+       for (i = 0; i < set->nr_hw_queues; i++) {
+               struct blk_mq_tags *tags = set->tags[i];
+
+               for (j = 0; j < tags->nr_tags; j++) {
+                       if (!tags->rqs[j])
+                               continue;
+
+                       ret = set->ops->reinit_request(set->driver_data,
+                                               tags->rqs[j]);
+                       if (ret)
+                               goto out;
+               }
+       }
+
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(blk_mq_reinit_tagset);
+
 void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
                void *priv)
 {
index cbfd8ca5f13ed4c82a5ebfa01b25b01daf300e84..e43bbffb5b7a35e51982b59fffd933fb34eb6e4c 100644 (file)
@@ -96,6 +96,7 @@ typedef int (init_request_fn)(void *, struct request *, unsigned int,
                unsigned int, unsigned int);
 typedef void (exit_request_fn)(void *, struct request *, unsigned int,
                unsigned int);
+typedef int (reinit_request_fn)(void *, struct request *);
 
 typedef void (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *,
                bool);
@@ -145,6 +146,7 @@ struct blk_mq_ops {
         */
        init_request_fn         *init_request;
        exit_request_fn         *exit_request;
+       reinit_request_fn       *reinit_request;
 };
 
 enum {
@@ -245,6 +247,7 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
 void blk_mq_freeze_queue(struct request_queue *q);
 void blk_mq_unfreeze_queue(struct request_queue *q);
 void blk_mq_freeze_queue_start(struct request_queue *q);
+int blk_mq_reinit_tagset(struct blk_mq_tag_set *set);
 
 void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues);