Firstly blk_mq_timeout_work() is always run exclusivley for each queue.

Secondly if .timeout() returns BLK_EH_RESET_TIMER or BLK_EH_HANDLED,
the flag of RQF_MQ_TIMEOUT_EXPIRED will be cleared for this request,
because the request will be requeued or freed for BLK_EH_HANDLED, and
for BLK_EH_RESET_TIMER, new timer has to be started for this req.

So this patch only sets the flag of RQF_MQ_TIMEOUT_EXPIRED when .timeout
returns neither BLK_EH_RESET_TIMER nor BLK_EH_HANDLED.

Cc: "jianchao.wang" <[email protected]>
Cc: Bart Van Assche <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Ming Lei <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Israel Rukshin <[email protected]>,
Cc: Max Gurtovoy <[email protected]>
Cc: Martin Steigerwald <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
---
 block/blk-mq.c      | 4 ++--
 block/blk-timeout.c | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 0dc9e341c2a7..d6a21898933d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -815,8 +815,6 @@ static void blk_mq_rq_timed_out(struct request *req, bool 
reserved)
        const struct blk_mq_ops *ops = req->q->mq_ops;
        enum blk_eh_timer_return ret = BLK_EH_RESET_TIMER;
 
-       req->rq_flags |= RQF_MQ_TIMEOUT_EXPIRED;
-
        if (ops->timeout)
                ret = ops->timeout(req, reserved);
 
@@ -834,9 +832,11 @@ static void blk_mq_rq_timed_out(struct request *req, bool 
reserved)
                blk_add_timer(req);
                break;
        case BLK_EH_NOT_HANDLED:
+               req->rq_flags |= RQF_MQ_TIMEOUT_EXPIRED;
                break;
        default:
                printk(KERN_ERR "block: bad eh return: %d\n", ret);
+               req->rq_flags |= RQF_MQ_TIMEOUT_EXPIRED;
                break;
        }
 }
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
index 652d4d4d3e97..f95d6e6cbc96 100644
--- a/block/blk-timeout.c
+++ b/block/blk-timeout.c
@@ -214,7 +214,6 @@ void blk_add_timer(struct request *req)
                req->timeout = q->rq_timeout;
 
        blk_rq_set_deadline(req, jiffies + req->timeout);
-       req->rq_flags &= ~RQF_MQ_TIMEOUT_EXPIRED;
 
        /*
         * Only the non-mq case needs to add the request to a protected list.
-- 
2.9.5

Reply via email to