xref: /linux/block/blk-timeout.c (revision 242f9dcb8ba6f68fcd217a119a7648a4f69290e9)
1*242f9dcbSJens Axboe /*
2*242f9dcbSJens Axboe  * Functions related to generic timeout handling of requests.
3*242f9dcbSJens Axboe  */
4*242f9dcbSJens Axboe #include <linux/kernel.h>
5*242f9dcbSJens Axboe #include <linux/module.h>
6*242f9dcbSJens Axboe #include <linux/blkdev.h>
7*242f9dcbSJens Axboe 
8*242f9dcbSJens Axboe #include "blk.h"
9*242f9dcbSJens Axboe 
10*242f9dcbSJens Axboe /*
11*242f9dcbSJens Axboe  * blk_delete_timer - Delete/cancel timer for a given function.
12*242f9dcbSJens Axboe  * @req:	request that we are canceling timer for
13*242f9dcbSJens Axboe  *
14*242f9dcbSJens Axboe  */
15*242f9dcbSJens Axboe void blk_delete_timer(struct request *req)
16*242f9dcbSJens Axboe {
17*242f9dcbSJens Axboe 	struct request_queue *q = req->q;
18*242f9dcbSJens Axboe 
19*242f9dcbSJens Axboe 	/*
20*242f9dcbSJens Axboe 	 * Nothing to detach
21*242f9dcbSJens Axboe 	 */
22*242f9dcbSJens Axboe 	if (!q->rq_timed_out_fn || !req->deadline)
23*242f9dcbSJens Axboe 		return;
24*242f9dcbSJens Axboe 
25*242f9dcbSJens Axboe 	list_del_init(&req->timeout_list);
26*242f9dcbSJens Axboe 
27*242f9dcbSJens Axboe 	if (list_empty(&q->timeout_list))
28*242f9dcbSJens Axboe 		del_timer(&q->timeout);
29*242f9dcbSJens Axboe }
30*242f9dcbSJens Axboe 
31*242f9dcbSJens Axboe static void blk_rq_timed_out(struct request *req)
32*242f9dcbSJens Axboe {
33*242f9dcbSJens Axboe 	struct request_queue *q = req->q;
34*242f9dcbSJens Axboe 	enum blk_eh_timer_return ret;
35*242f9dcbSJens Axboe 
36*242f9dcbSJens Axboe 	ret = q->rq_timed_out_fn(req);
37*242f9dcbSJens Axboe 	switch (ret) {
38*242f9dcbSJens Axboe 	case BLK_EH_HANDLED:
39*242f9dcbSJens Axboe 		__blk_complete_request(req);
40*242f9dcbSJens Axboe 		break;
41*242f9dcbSJens Axboe 	case BLK_EH_RESET_TIMER:
42*242f9dcbSJens Axboe 		blk_clear_rq_complete(req);
43*242f9dcbSJens Axboe 		blk_add_timer(req);
44*242f9dcbSJens Axboe 		break;
45*242f9dcbSJens Axboe 	case BLK_EH_NOT_HANDLED:
46*242f9dcbSJens Axboe 		/*
47*242f9dcbSJens Axboe 		 * LLD handles this for now but in the future
48*242f9dcbSJens Axboe 		 * we can send a request msg to abort the command
49*242f9dcbSJens Axboe 		 * and we can move more of the generic scsi eh code to
50*242f9dcbSJens Axboe 		 * the blk layer.
51*242f9dcbSJens Axboe 		 */
52*242f9dcbSJens Axboe 		break;
53*242f9dcbSJens Axboe 	default:
54*242f9dcbSJens Axboe 		printk(KERN_ERR "block: bad eh return: %d\n", ret);
55*242f9dcbSJens Axboe 		break;
56*242f9dcbSJens Axboe 	}
57*242f9dcbSJens Axboe }
58*242f9dcbSJens Axboe 
59*242f9dcbSJens Axboe void blk_rq_timed_out_timer(unsigned long data)
60*242f9dcbSJens Axboe {
61*242f9dcbSJens Axboe 	struct request_queue *q = (struct request_queue *) data;
62*242f9dcbSJens Axboe 	unsigned long flags, uninitialized_var(next), next_set = 0;
63*242f9dcbSJens Axboe 	struct request *rq, *tmp;
64*242f9dcbSJens Axboe 
65*242f9dcbSJens Axboe 	spin_lock_irqsave(q->queue_lock, flags);
66*242f9dcbSJens Axboe 
67*242f9dcbSJens Axboe 	list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) {
68*242f9dcbSJens Axboe 		if (time_after_eq(jiffies, rq->deadline)) {
69*242f9dcbSJens Axboe 			list_del_init(&rq->timeout_list);
70*242f9dcbSJens Axboe 
71*242f9dcbSJens Axboe 			/*
72*242f9dcbSJens Axboe 			 * Check if we raced with end io completion
73*242f9dcbSJens Axboe 			 */
74*242f9dcbSJens Axboe 			if (blk_mark_rq_complete(rq))
75*242f9dcbSJens Axboe 				continue;
76*242f9dcbSJens Axboe 			blk_rq_timed_out(rq);
77*242f9dcbSJens Axboe 		}
78*242f9dcbSJens Axboe 		if (!next_set) {
79*242f9dcbSJens Axboe 			next = rq->deadline;
80*242f9dcbSJens Axboe 			next_set = 1;
81*242f9dcbSJens Axboe 		} else if (time_after(next, rq->deadline))
82*242f9dcbSJens Axboe 			next = rq->deadline;
83*242f9dcbSJens Axboe 	}
84*242f9dcbSJens Axboe 
85*242f9dcbSJens Axboe 	if (next_set && !list_empty(&q->timeout_list))
86*242f9dcbSJens Axboe 		mod_timer(&q->timeout, round_jiffies(next));
87*242f9dcbSJens Axboe 
88*242f9dcbSJens Axboe 	spin_unlock_irqrestore(q->queue_lock, flags);
89*242f9dcbSJens Axboe }
90*242f9dcbSJens Axboe 
91*242f9dcbSJens Axboe /**
92*242f9dcbSJens Axboe  * blk_abort_request -- Request request recovery for the specified command
93*242f9dcbSJens Axboe  * @req:	pointer to the request of interest
94*242f9dcbSJens Axboe  *
95*242f9dcbSJens Axboe  * This function requests that the block layer start recovery for the
96*242f9dcbSJens Axboe  * request by deleting the timer and calling the q's timeout function.
97*242f9dcbSJens Axboe  * LLDDs who implement their own error recovery MAY ignore the timeout
98*242f9dcbSJens Axboe  * event if they generated blk_abort_req. Must hold queue lock.
99*242f9dcbSJens Axboe  */
100*242f9dcbSJens Axboe void blk_abort_request(struct request *req)
101*242f9dcbSJens Axboe {
102*242f9dcbSJens Axboe 	blk_delete_timer(req);
103*242f9dcbSJens Axboe 	blk_rq_timed_out(req);
104*242f9dcbSJens Axboe }
105*242f9dcbSJens Axboe EXPORT_SYMBOL_GPL(blk_abort_request);
106*242f9dcbSJens Axboe 
107*242f9dcbSJens Axboe /**
108*242f9dcbSJens Axboe  * blk_add_timer - Start timeout timer for a single request
109*242f9dcbSJens Axboe  * @req:	request that is about to start running.
110*242f9dcbSJens Axboe  *
111*242f9dcbSJens Axboe  * Notes:
112*242f9dcbSJens Axboe  *    Each request has its own timer, and as it is added to the queue, we
113*242f9dcbSJens Axboe  *    set up the timer. When the request completes, we cancel the timer.
114*242f9dcbSJens Axboe  */
115*242f9dcbSJens Axboe void blk_add_timer(struct request *req)
116*242f9dcbSJens Axboe {
117*242f9dcbSJens Axboe 	struct request_queue *q = req->q;
118*242f9dcbSJens Axboe 	unsigned long expiry;
119*242f9dcbSJens Axboe 
120*242f9dcbSJens Axboe 	if (!q->rq_timed_out_fn)
121*242f9dcbSJens Axboe 		return;
122*242f9dcbSJens Axboe 
123*242f9dcbSJens Axboe 	BUG_ON(!list_empty(&req->timeout_list));
124*242f9dcbSJens Axboe 	BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
125*242f9dcbSJens Axboe 
126*242f9dcbSJens Axboe 	if (req->timeout)
127*242f9dcbSJens Axboe 		req->deadline = jiffies + req->timeout;
128*242f9dcbSJens Axboe 	else {
129*242f9dcbSJens Axboe 		req->deadline = jiffies + q->rq_timeout;
130*242f9dcbSJens Axboe 		/*
131*242f9dcbSJens Axboe 		 * Some LLDs, like scsi, peek at the timeout to prevent
132*242f9dcbSJens Axboe 		 * a command from being retried forever.
133*242f9dcbSJens Axboe 		 */
134*242f9dcbSJens Axboe 		req->timeout = q->rq_timeout;
135*242f9dcbSJens Axboe 	}
136*242f9dcbSJens Axboe 	list_add_tail(&req->timeout_list, &q->timeout_list);
137*242f9dcbSJens Axboe 
138*242f9dcbSJens Axboe 	/*
139*242f9dcbSJens Axboe 	 * If the timer isn't already pending or this timeout is earlier
140*242f9dcbSJens Axboe 	 * than an existing one, modify the timer. Round to next nearest
141*242f9dcbSJens Axboe 	 * second.
142*242f9dcbSJens Axboe 	 */
143*242f9dcbSJens Axboe 	expiry = round_jiffies(req->deadline);
144*242f9dcbSJens Axboe 
145*242f9dcbSJens Axboe 	/*
146*242f9dcbSJens Axboe 	 * We use ->deadline == 0 to detect whether a timer was added or
147*242f9dcbSJens Axboe 	 * not, so just increase to next jiffy for that specific case
148*242f9dcbSJens Axboe 	 */
149*242f9dcbSJens Axboe 	if (unlikely(!req->deadline))
150*242f9dcbSJens Axboe 		req->deadline = 1;
151*242f9dcbSJens Axboe 
152*242f9dcbSJens Axboe 	if (!timer_pending(&q->timeout) ||
153*242f9dcbSJens Axboe 	    time_before(expiry, q->timeout.expires))
154*242f9dcbSJens Axboe 		mod_timer(&q->timeout, expiry);
155*242f9dcbSJens Axboe }
156