diff --git a/block/blk-core.c b/block/blk-core.c index 8b93366c76e417115adf099a6ac8a778fbb71abb..715b61c239ea6ef1046789fd875ce2440907abe6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1304,7 +1304,8 @@ void blk_account_io_done(struct request *req, u64 now) * This might fail if 'stat_time_ns' is updated * in blk_mq_check_inflight_with_stat(). */ - if (likely(cmpxchg64(&rq_wrapper->stat_time_ns, stat_time, now) + if (likely(now > stat_time && + cmpxchg64(&rq_wrapper->stat_time_ns, stat_time, now) == stat_time)) { u64 duation = stat_time ? now - stat_time : now - req->start_time_ns; diff --git a/block/blk-mq.c b/block/blk-mq.c index 76ff229e7fb2dcc742eaba549fc049a631925e04..5031c4fc4412f0393cd2d5fd09d65efad1cb0eed 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -117,14 +117,22 @@ static bool blk_mq_check_inflight_with_stat(struct blk_mq_hw_ctx *hctx, if (!rq->part) return true; + /* + * If the request is started after 'part->stat_time' is set, + * don't update 'nsces' here. + */ + if (rq->part->stat_time <= rq->start_time_ns) + return true; + rq_wrapper = request_to_wrapper(rq); stat_time = READ_ONCE(rq_wrapper->stat_time_ns); /* * This might fail if 'stat_time_ns' is updated in * blk_account_io_done(). */ - if (likely(cmpxchg64(&rq_wrapper->stat_time_ns, stat_time, - rq->part->stat_time) == stat_time)) { + if (likely(rq->part->stat_time > stat_time && + cmpxchg64(&rq_wrapper->stat_time_ns, stat_time, + rq->part->stat_time) == stat_time)) { int sgrp = op_stat_group(req_op(rq)); u64 duation = stat_time ? rq->part->stat_time - stat_time :