Skip to content

Commit 4e2f62e

Browse files
committed
Revert "blk-mq: put driver tag when this request is completed"
This reverts commits the following commits: 37f4a24 723bf17 36a3df5 The last one is the culprit, but we have to go a bit deeper to get this to revert cleanly. There's been a report that this breaks some MMC setups [1], and also causes an issue with swap [2]. Until this can be figured out, revert the offending commits. [1] https://lore.kernel.org/linux-block/[email protected]/ [2] https://lore.kernel.org/linux-block/[email protected]/ Reported-by: Marek Szyprowski <[email protected]> Reported-by: Qian Cai <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent b53ac8b commit 4e2f62e

File tree

5 files changed

+70
-42
lines changed

5 files changed

+70
-42
lines changed

block/blk-flush.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,13 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
236236
error = fq->rq_status;
237237

238238
hctx = flush_rq->mq_hctx;
239-
if (!q->elevator)
240-
flush_rq->tag = BLK_MQ_NO_TAG;
241-
else
242-
flush_rq->internal_tag = BLK_MQ_NO_TAG;
239+
if (!q->elevator) {
240+
blk_mq_tag_set_rq(hctx, flush_rq->tag, fq->orig_rq);
241+
flush_rq->tag = -1;
242+
} else {
243+
blk_mq_put_driver_tag(flush_rq);
244+
flush_rq->internal_tag = -1;
245+
}
243246

244247
running = &fq->flush_queue[fq->flush_running_idx];
245248
BUG_ON(fq->flush_pending_idx == fq->flush_running_idx);
@@ -313,10 +316,13 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
313316
flush_rq->mq_ctx = first_rq->mq_ctx;
314317
flush_rq->mq_hctx = first_rq->mq_hctx;
315318

316-
if (!q->elevator)
319+
if (!q->elevator) {
320+
fq->orig_rq = first_rq;
317321
flush_rq->tag = first_rq->tag;
318-
else
322+
blk_mq_tag_set_rq(flush_rq->mq_hctx, first_rq->tag, flush_rq);
323+
} else {
319324
flush_rq->internal_tag = first_rq->internal_tag;
325+
}
320326

321327
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
322328
flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK);
@@ -335,6 +341,11 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error)
335341
unsigned long flags;
336342
struct blk_flush_queue *fq = blk_get_flush_queue(q, ctx);
337343

344+
if (q->elevator) {
345+
WARN_ON(rq->tag < 0);
346+
blk_mq_put_driver_tag(rq);
347+
}
348+
338349
/*
339350
* After populating an empty queue, kick it to avoid stall. Read
340351
* the comment in flush_end_io().

block/blk-mq-tag.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
101101
return atomic_read(&hctx->nr_active) < depth;
102102
}
103103

104+
/*
105+
* This helper should only be used for flush request to share tag
106+
* with the request cloned from, and both the two requests can't be
107+
* in flight at the same time. The caller has to make sure the tag
108+
* can't be freed.
109+
*/
110+
static inline void blk_mq_tag_set_rq(struct blk_mq_hw_ctx *hctx,
111+
unsigned int tag, struct request *rq)
112+
{
113+
hctx->tags->rqs[tag] = rq;
114+
}
115+
104116
static inline bool blk_mq_tag_is_reserved(struct blk_mq_tags *tags,
105117
unsigned int tag)
106118
{

block/blk-mq.c

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -277,20 +277,26 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
277277
{
278278
struct blk_mq_tags *tags = blk_mq_tags_from_data(data);
279279
struct request *rq = tags->static_rqs[tag];
280+
req_flags_t rq_flags = 0;
280281

281282
if (data->q->elevator) {
282283
rq->tag = BLK_MQ_NO_TAG;
283284
rq->internal_tag = tag;
284285
} else {
286+
if (data->hctx->flags & BLK_MQ_F_TAG_SHARED) {
287+
rq_flags = RQF_MQ_INFLIGHT;
288+
atomic_inc(&data->hctx->nr_active);
289+
}
285290
rq->tag = tag;
286291
rq->internal_tag = BLK_MQ_NO_TAG;
292+
data->hctx->tags->rqs[rq->tag] = rq;
287293
}
288294

289295
/* csd/requeue_work/fifo_time is initialized before use */
290296
rq->q = data->q;
291297
rq->mq_ctx = data->ctx;
292298
rq->mq_hctx = data->hctx;
293-
rq->rq_flags = 0;
299+
rq->rq_flags = rq_flags;
294300
rq->cmd_flags = data->cmd_flags;
295301
if (data->flags & BLK_MQ_REQ_PREEMPT)
296302
rq->rq_flags |= RQF_PREEMPT;
@@ -660,32 +666,10 @@ static inline bool blk_mq_complete_need_ipi(struct request *rq)
660666
return cpu_online(rq->mq_ctx->cpu);
661667
}
662668

663-
static void __blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx,
664-
struct request *rq)
665-
{
666-
blk_mq_put_tag(hctx->tags, rq->mq_ctx, rq->tag);
667-
rq->tag = BLK_MQ_NO_TAG;
668-
669-
if (rq->rq_flags & RQF_MQ_INFLIGHT) {
670-
rq->rq_flags &= ~RQF_MQ_INFLIGHT;
671-
atomic_dec(&hctx->nr_active);
672-
}
673-
}
674-
675-
static inline void blk_mq_put_driver_tag(struct request *rq)
676-
{
677-
if (rq->tag == BLK_MQ_NO_TAG || rq->internal_tag == BLK_MQ_NO_TAG)
678-
return;
679-
680-
__blk_mq_put_driver_tag(rq->mq_hctx, rq);
681-
}
682-
683669
bool blk_mq_complete_request_remote(struct request *rq)
684670
{
685671
WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
686672

687-
blk_mq_put_driver_tag(rq);
688-
689673
/*
690674
* For a polled request, always complete locallly, it's pointless
691675
* to redirect the completion.
@@ -1121,10 +1105,9 @@ static bool __blk_mq_get_driver_tag(struct request *rq)
11211105
{
11221106
struct sbitmap_queue *bt = &rq->mq_hctx->tags->bitmap_tags;
11231107
unsigned int tag_offset = rq->mq_hctx->tags->nr_reserved_tags;
1108+
bool shared = blk_mq_tag_busy(rq->mq_hctx);
11241109
int tag;
11251110

1126-
blk_mq_tag_busy(rq->mq_hctx);
1127-
11281111
if (blk_mq_tag_is_reserved(rq->mq_hctx->sched_tags, rq->internal_tag)) {
11291112
bt = &rq->mq_hctx->tags->breserved_tags;
11301113
tag_offset = 0;
@@ -1137,22 +1120,19 @@ static bool __blk_mq_get_driver_tag(struct request *rq)
11371120
return false;
11381121

11391122
rq->tag = tag + tag_offset;
1123+
if (shared) {
1124+
rq->rq_flags |= RQF_MQ_INFLIGHT;
1125+
atomic_inc(&rq->mq_hctx->nr_active);
1126+
}
1127+
rq->mq_hctx->tags->rqs[rq->tag] = rq;
11401128
return true;
11411129
}
11421130

11431131
static bool blk_mq_get_driver_tag(struct request *rq)
11441132
{
1145-
struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
1146-
1147-
if (rq->tag == BLK_MQ_NO_TAG && !__blk_mq_get_driver_tag(rq))
1148-
return false;
1149-
1150-
if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
1151-
rq->rq_flags |= RQF_MQ_INFLIGHT;
1152-
atomic_inc(&hctx->nr_active);
1153-
}
1154-
hctx->tags->rqs[rq->tag] = rq;
1155-
return true;
1133+
if (rq->tag != BLK_MQ_NO_TAG)
1134+
return true;
1135+
return __blk_mq_get_driver_tag(rq);
11561136
}
11571137

11581138
static int blk_mq_dispatch_wake(wait_queue_entry_t *wait, unsigned mode,

block/blk-mq.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,26 @@ static inline bool blk_mq_get_dispatch_budget(struct request_queue *q)
193193
return true;
194194
}
195195

196+
static inline void __blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx,
197+
struct request *rq)
198+
{
199+
blk_mq_put_tag(hctx->tags, rq->mq_ctx, rq->tag);
200+
rq->tag = BLK_MQ_NO_TAG;
201+
202+
if (rq->rq_flags & RQF_MQ_INFLIGHT) {
203+
rq->rq_flags &= ~RQF_MQ_INFLIGHT;
204+
atomic_dec(&hctx->nr_active);
205+
}
206+
}
207+
208+
static inline void blk_mq_put_driver_tag(struct request *rq)
209+
{
210+
if (rq->tag == BLK_MQ_NO_TAG || rq->internal_tag == BLK_MQ_NO_TAG)
211+
return;
212+
213+
__blk_mq_put_driver_tag(rq->mq_hctx, rq);
214+
}
215+
196216
static inline void blk_mq_clear_mq_map(struct blk_mq_queue_map *qmap)
197217
{
198218
int cpu;

block/blk.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ struct blk_flush_queue {
2525
struct list_head flush_data_in_flight;
2626
struct request *flush_rq;
2727

28+
/*
29+
* flush_rq shares tag with this rq, both can't be active
30+
* at the same time
31+
*/
32+
struct request *orig_rq;
2833
struct lock_class_key key;
2934
spinlock_t mq_flush_lock;
3035
};

0 commit comments

Comments
 (0)