block: clarify blk_add_timer() use case for blk-mq
[cascardo/linux.git] / block / blk-timeout.c
index 56c0258..3610af5 100644 (file)
@@ -158,11 +158,13 @@ void blk_abort_request(struct request *req)
 {
        if (blk_mark_rq_complete(req))
                return;
-       blk_delete_timer(req);
-       if (req->q->mq_ops)
+
+       if (req->q->mq_ops) {
                blk_mq_rq_timed_out(req, false);
-       else
+       } else {
+               blk_delete_timer(req);
                blk_rq_timed_out(req);
+       }
 }
 EXPORT_SYMBOL_GPL(blk_abort_request);
 
@@ -184,12 +186,16 @@ unsigned long blk_rq_timeout(unsigned long timeout)
  * Notes:
  *    Each request has its own timer, and as it is added to the queue, we
  *    set up the timer. When the request completes, we cancel the timer.
+ *    Queue lock must be held for the non-mq case, mq case doesn't care.
  */
 void blk_add_timer(struct request *req)
 {
        struct request_queue *q = req->q;
        unsigned long expiry;
 
+       if (req->cmd_flags & REQ_NO_TIMEOUT)
+               return;
+
        /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */
        if (!q->mq_ops && !q->rq_timed_out_fn)
                return;
@@ -204,6 +210,11 @@ void blk_add_timer(struct request *req)
                req->timeout = q->rq_timeout;
 
        req->deadline = jiffies + req->timeout;
+
+       /*
+        * Only the non-mq case needs to add the request to a protected list.
+        * For the mq case we simply scan the tag map.
+        */
        if (!q->mq_ops)
                list_add_tail(&req->timeout_list, &req->q->timeout_list);