Commit a534dbe96e9929c7245924d8252d89048c23d569

Authored by Richard Kennedy
Committed by Jens Axboe
1 parent 05ce7bfe54

block: ensure jiffies wrap is handled correctly in blk_rq_timed_out_timer

blk_rq_timed_out_timer() relied on blk_add_timer() never returning a
timer value of zero, but commit 7838c15b8dd18e78a523513749e5b54bda07b0cb
removed the code that bumped this value when it was zero.
Therefore when jiffies is near wrap we could get unlucky & not set the
timeout value correctly.

This patch uses a flag to indicate that the timeout value was set and so
handles jiffies wrap correctly, and it keeps all the logic in one
function so should be easier to maintain in the future.

Signed-off-by: Richard Kennedy <richard@rsk.demon.co.uk>
Cc: stable@kernel.org
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 1 changed file with 5 additions and 7 deletions Side-by-side Diff

... ... @@ -109,6 +109,7 @@
109 109 struct request_queue *q = (struct request_queue *) data;
110 110 unsigned long flags, next = 0;
111 111 struct request *rq, *tmp;
  112 + int next_set = 0;
112 113  
113 114 spin_lock_irqsave(q->queue_lock, flags);
114 115  
115 116  
116 117  
... ... @@ -122,16 +123,13 @@
122 123 if (blk_mark_rq_complete(rq))
123 124 continue;
124 125 blk_rq_timed_out(rq);
125   - } else if (!next || time_after(next, rq->deadline))
  126 + } else if (!next_set || time_after(next, rq->deadline)) {
126 127 next = rq->deadline;
  128 + next_set = 1;
  129 + }
127 130 }
128 131  
129   - /*
130   - * next can never be 0 here with the list non-empty, since we always
131   - * bump ->deadline to 1 so we can detect if the timer was ever added
132   - * or not. See comment in blk_add_timer()
133   - */
134   - if (next)
  132 + if (next_set)
135 133 mod_timer(&q->timeout, round_jiffies_up(next));
136 134  
137 135 spin_unlock_irqrestore(q->queue_lock, flags);