Skip to content

Commit 002c0ae

Browse files
committed
Merge tag 'block-5.14-2021-08-20' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "Three fixes from Ming Lei that should go into 5.14: - Fix for a kernel panic when iterating over tags for some cases where a flush request is present, a regression in this cycle. - Request timeout fix - Fix flush request checking" * tag 'block-5.14-2021-08-20' of git://git.kernel.dk/linux-block: blk-mq: fix is_flush_rq blk-mq: fix kernel panic during iterating over flush request blk-mq: don't grab rq's refcount in blk_mq_check_expired()
2 parents 1e6907d + a9ed27a commit 002c0ae

File tree

4 files changed

+20
-32
lines changed

4 files changed

+20
-32
lines changed

block/blk-core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
122122
rq->internal_tag = BLK_MQ_NO_TAG;
123123
rq->start_time_ns = ktime_get_ns();
124124
rq->part = NULL;
125-
refcount_set(&rq->ref, 1);
126125
blk_crypto_rq_set_defaults(rq);
127126
}
128127
EXPORT_SYMBOL(blk_rq_init);

block/blk-flush.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
262262
spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
263263
}
264264

265+
bool is_flush_rq(struct request *rq)
266+
{
267+
return rq->end_io == flush_end_io;
268+
}
269+
265270
/**
266271
* blk_kick_flush - consider issuing flush request
267272
* @q: request_queue being kicked
@@ -329,6 +334,14 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
329334
flush_rq->rq_flags |= RQF_FLUSH_SEQ;
330335
flush_rq->rq_disk = first_rq->rq_disk;
331336
flush_rq->end_io = flush_end_io;
337+
/*
338+
* Order WRITE ->end_io and WRITE rq->ref, and its pair is the one
339+
* implied in refcount_inc_not_zero() called from
340+
* blk_mq_find_and_get_req(), which orders WRITE/READ flush_rq->ref
341+
* and READ flush_rq->end_io
342+
*/
343+
smp_wmb();
344+
refcount_set(&flush_rq->ref, 1);
332345

333346
blk_flush_queue_rq(flush_rq, false);
334347
}

block/blk-mq.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
911911

912912
void blk_mq_put_rq_ref(struct request *rq)
913913
{
914-
if (is_flush_rq(rq, rq->mq_hctx))
914+
if (is_flush_rq(rq))
915915
rq->end_io(rq, 0);
916916
else if (refcount_dec_and_test(&rq->ref))
917917
__blk_mq_free_request(rq);
@@ -923,34 +923,14 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
923923
unsigned long *next = priv;
924924

925925
/*
926-
* Just do a quick check if it is expired before locking the request in
927-
* so we're not unnecessarilly synchronizing across CPUs.
928-
*/
929-
if (!blk_mq_req_expired(rq, next))
930-
return true;
931-
932-
/*
933-
* We have reason to believe the request may be expired. Take a
934-
* reference on the request to lock this request lifetime into its
935-
* currently allocated context to prevent it from being reallocated in
936-
* the event the completion by-passes this timeout handler.
937-
*
938-
* If the reference was already released, then the driver beat the
939-
* timeout handler to posting a natural completion.
940-
*/
941-
if (!refcount_inc_not_zero(&rq->ref))
942-
return true;
943-
944-
/*
945-
* The request is now locked and cannot be reallocated underneath the
946-
* timeout handler's processing. Re-verify this exact request is truly
947-
* expired; if it is not expired, then the request was completed and
948-
* reallocated as a new request.
926+
* blk_mq_queue_tag_busy_iter() has locked the request, so it cannot
927+
* be reallocated underneath the timeout handler's processing, then
928+
* the expire check is reliable. If the request is not expired, then
929+
* it was completed and reallocated as a new request after returning
930+
* from blk_mq_check_expired().
949931
*/
950932
if (blk_mq_req_expired(rq, next))
951933
blk_mq_rq_timed_out(rq, reserved);
952-
953-
blk_mq_put_rq_ref(rq);
954934
return true;
955935
}
956936

block/blk.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ static inline void __blk_get_queue(struct request_queue *q)
4444
kobject_get(&q->kobj);
4545
}
4646

47-
static inline bool
48-
is_flush_rq(struct request *req, struct blk_mq_hw_ctx *hctx)
49-
{
50-
return hctx->fq->flush_rq == req;
51-
}
47+
bool is_flush_rq(struct request *req);
5248

5349
struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
5450
gfp_t flags);

0 commit comments

Comments
 (0)