From: Chengming Zhou <zhouchengming@xxxxxxxxxxxxx> CPU0 CPU1 blk_mq_start_request() blk_mq_req_expired() WRITE_ONCE(rq->deadline) WRITE_ONCE(rq->state) if (READ_ONCE(rq->state) != IN_FLIGHT) return deadline = READ_ONCE(rq->deadline) If CPU1 speculately reorder rq->deadline LOAD before rq->state, the deadline will be the initial value 0. CPU0 CPU1 blk_mq_start_request() blk_mq_req_expired() deadline = READ_ONCE(rq->deadline) WRITE_ONCE(rq->deadline) WRITE_ONCE(rq->state) if (READ_ONCE(rq->state) != IN_FLIGHT) return Signed-off-by: Chengming Zhou <zhouchengming@xxxxxxxxxxxxx> --- block/blk-mq.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/blk-mq.c b/block/blk-mq.c index ff1b0f3ab3a8..49cbf826b100 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1258,6 +1258,8 @@ void blk_mq_start_request(struct request *rq) WARN_ON_ONCE(blk_mq_rq_state(rq) != MQ_RQ_IDLE); blk_add_timer(rq); + /* Pair with smp_rmb in blk_mq_req_expired(). */ + smp_wmb(); WRITE_ONCE(rq->state, MQ_RQ_IN_FLIGHT); rq->mq_hctx->tags->rqs[rq->tag] = rq; @@ -1568,6 +1570,12 @@ static bool blk_mq_req_expired(struct request *rq, struct blk_expired_data *expi if (rq->rq_flags & RQF_TIMED_OUT) return false; + /* + * Order LOADs of rq->state and rq->deadline, pair with + * smp_wmb in blk_mq_start_request(). + */ + smp_rmb(); + deadline = READ_ONCE(rq->deadline); if (time_after_eq(expired->timeout_start, deadline)) return true; -- 2.41.0