On 12/20/18 6:02 AM, Jens Axboe wrote:
>> I'm afraid this cannot work.
>>
>> The 'tags' here could be the hctx->sched_tags, but what we need to
>> clear is hctx->tags->rqs[].
> 
> You are right, of course, a bit too quick on the trigger. This one
> should work better, and also avoids that silly quadratic loop. I don't
> think we need the tag == -1 check, but probably best to be safe.

Sent out the wrong one, here it is. Bart, if you can reproduce, can you
give it a whirl?


diff --git a/block/blk-mq.c b/block/blk-mq.c
index 2de972857496..fc04bb648f18 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2025,7 +2025,7 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct 
blk_mq_tags *tags,
 {
        struct page *page;
 
-       if (tags->rqs && set->ops->exit_request) {
+       if (tags->rqs) {
                int i;
 
                for (i = 0; i < tags->nr_tags; i++) {
@@ -2033,8 +2033,14 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct 
blk_mq_tags *tags,
 
                        if (!rq)
                                continue;
-                       set->ops->exit_request(set, rq, hctx_idx);
+                       if (set->ops->exit_request)
+                               set->ops->exit_request(set, rq, hctx_idx);
                        tags->static_rqs[i] = NULL;
+
+                       if (rq->tag == -1)
+                               continue;
+                       if (set->tags[hctx_idx]->rqs[rq->tag] == rq)
+                               set->tags[hctx_idx]->rqs[rq->tag] = NULL;
                }
        }
 
@@ -2113,6 +2119,7 @@ static int blk_mq_init_request(struct blk_mq_tag_set 
*set, struct request *rq,
                        return ret;
        }
 
+       rq->tag = -1;
        WRITE_ONCE(rq->state, MQ_RQ_IDLE);
        return 0;
 }

-- 
Jens Axboe

Reply via email to