xref: /linux/block/blk-timeout.c (revision 30a91cb4ef385fe1b260df204ef314d86fff2850)
1242f9dcbSJens Axboe /*
2242f9dcbSJens Axboe  * Functions related to generic timeout handling of requests.
3242f9dcbSJens Axboe  */
4242f9dcbSJens Axboe #include <linux/kernel.h>
5242f9dcbSJens Axboe #include <linux/module.h>
6242f9dcbSJens Axboe #include <linux/blkdev.h>
7581d4e28SJens Axboe #include <linux/fault-inject.h>
8242f9dcbSJens Axboe 
9242f9dcbSJens Axboe #include "blk.h"
10320ae51fSJens Axboe #include "blk-mq.h"
11242f9dcbSJens Axboe 
12581d4e28SJens Axboe #ifdef CONFIG_FAIL_IO_TIMEOUT
13581d4e28SJens Axboe 
14581d4e28SJens Axboe static DECLARE_FAULT_ATTR(fail_io_timeout);
15581d4e28SJens Axboe 
16581d4e28SJens Axboe static int __init setup_fail_io_timeout(char *str)
17581d4e28SJens Axboe {
18581d4e28SJens Axboe 	return setup_fault_attr(&fail_io_timeout, str);
19581d4e28SJens Axboe }
20581d4e28SJens Axboe __setup("fail_io_timeout=", setup_fail_io_timeout);
21581d4e28SJens Axboe 
22581d4e28SJens Axboe int blk_should_fake_timeout(struct request_queue *q)
23581d4e28SJens Axboe {
24581d4e28SJens Axboe 	if (!test_bit(QUEUE_FLAG_FAIL_IO, &q->queue_flags))
25581d4e28SJens Axboe 		return 0;
26581d4e28SJens Axboe 
27581d4e28SJens Axboe 	return should_fail(&fail_io_timeout, 1);
28581d4e28SJens Axboe }
29581d4e28SJens Axboe 
30581d4e28SJens Axboe static int __init fail_io_timeout_debugfs(void)
31581d4e28SJens Axboe {
32dd48c085SAkinobu Mita 	struct dentry *dir = fault_create_debugfs_attr("fail_io_timeout",
33dd48c085SAkinobu Mita 						NULL, &fail_io_timeout);
34dd48c085SAkinobu Mita 
358616ebb1SDuan Jiong 	return PTR_ERR_OR_ZERO(dir);
36581d4e28SJens Axboe }
37581d4e28SJens Axboe 
38581d4e28SJens Axboe late_initcall(fail_io_timeout_debugfs);
39581d4e28SJens Axboe 
40581d4e28SJens Axboe ssize_t part_timeout_show(struct device *dev, struct device_attribute *attr,
41581d4e28SJens Axboe 			  char *buf)
42581d4e28SJens Axboe {
43581d4e28SJens Axboe 	struct gendisk *disk = dev_to_disk(dev);
44581d4e28SJens Axboe 	int set = test_bit(QUEUE_FLAG_FAIL_IO, &disk->queue->queue_flags);
45581d4e28SJens Axboe 
46581d4e28SJens Axboe 	return sprintf(buf, "%d\n", set != 0);
47581d4e28SJens Axboe }
48581d4e28SJens Axboe 
49581d4e28SJens Axboe ssize_t part_timeout_store(struct device *dev, struct device_attribute *attr,
50581d4e28SJens Axboe 			   const char *buf, size_t count)
51581d4e28SJens Axboe {
52581d4e28SJens Axboe 	struct gendisk *disk = dev_to_disk(dev);
53581d4e28SJens Axboe 	int val;
54581d4e28SJens Axboe 
55581d4e28SJens Axboe 	if (count) {
56581d4e28SJens Axboe 		struct request_queue *q = disk->queue;
57581d4e28SJens Axboe 		char *p = (char *) buf;
58581d4e28SJens Axboe 
59581d4e28SJens Axboe 		val = simple_strtoul(p, &p, 10);
60581d4e28SJens Axboe 		spin_lock_irq(q->queue_lock);
61581d4e28SJens Axboe 		if (val)
62581d4e28SJens Axboe 			queue_flag_set(QUEUE_FLAG_FAIL_IO, q);
63581d4e28SJens Axboe 		else
64581d4e28SJens Axboe 			queue_flag_clear(QUEUE_FLAG_FAIL_IO, q);
65581d4e28SJens Axboe 		spin_unlock_irq(q->queue_lock);
66581d4e28SJens Axboe 	}
67581d4e28SJens Axboe 
68581d4e28SJens Axboe 	return count;
69581d4e28SJens Axboe }
70581d4e28SJens Axboe 
71581d4e28SJens Axboe #endif /* CONFIG_FAIL_IO_TIMEOUT */
72581d4e28SJens Axboe 
73242f9dcbSJens Axboe /*
74242f9dcbSJens Axboe  * blk_delete_timer - Delete/cancel timer for a given function.
75242f9dcbSJens Axboe  * @req:	request that we are canceling timer for
76242f9dcbSJens Axboe  *
77242f9dcbSJens Axboe  */
78242f9dcbSJens Axboe void blk_delete_timer(struct request *req)
79242f9dcbSJens Axboe {
80242f9dcbSJens Axboe 	list_del_init(&req->timeout_list);
81242f9dcbSJens Axboe }
82242f9dcbSJens Axboe 
83242f9dcbSJens Axboe static void blk_rq_timed_out(struct request *req)
84242f9dcbSJens Axboe {
85242f9dcbSJens Axboe 	struct request_queue *q = req->q;
8680bd7181SHannes Reinecke 	enum blk_eh_timer_return ret = BLK_EH_RESET_TIMER;
87242f9dcbSJens Axboe 
8880bd7181SHannes Reinecke 	if (q->rq_timed_out_fn)
89242f9dcbSJens Axboe 		ret = q->rq_timed_out_fn(req);
90242f9dcbSJens Axboe 	switch (ret) {
91242f9dcbSJens Axboe 	case BLK_EH_HANDLED:
92320ae51fSJens Axboe 		/* Can we use req->errors here? */
93320ae51fSJens Axboe 		if (q->mq_ops)
94*30a91cb4SChristoph Hellwig 			__blk_mq_complete_request(req);
95320ae51fSJens Axboe 		else
96242f9dcbSJens Axboe 			__blk_complete_request(req);
97242f9dcbSJens Axboe 		break;
98242f9dcbSJens Axboe 	case BLK_EH_RESET_TIMER:
99320ae51fSJens Axboe 		if (q->mq_ops)
100320ae51fSJens Axboe 			blk_mq_add_timer(req);
101320ae51fSJens Axboe 		else
102242f9dcbSJens Axboe 			blk_add_timer(req);
103e37459b8SJens Axboe 
1044912aa6cSJeff Moyer 		blk_clear_rq_complete(req);
105242f9dcbSJens Axboe 		break;
106242f9dcbSJens Axboe 	case BLK_EH_NOT_HANDLED:
107242f9dcbSJens Axboe 		/*
108242f9dcbSJens Axboe 		 * LLD handles this for now but in the future
109242f9dcbSJens Axboe 		 * we can send a request msg to abort the command
110242f9dcbSJens Axboe 		 * and we can move more of the generic scsi eh code to
111242f9dcbSJens Axboe 		 * the blk layer.
112242f9dcbSJens Axboe 		 */
113242f9dcbSJens Axboe 		break;
114242f9dcbSJens Axboe 	default:
115242f9dcbSJens Axboe 		printk(KERN_ERR "block: bad eh return: %d\n", ret);
116242f9dcbSJens Axboe 		break;
117242f9dcbSJens Axboe 	}
118242f9dcbSJens Axboe }
119242f9dcbSJens Axboe 
120320ae51fSJens Axboe void blk_rq_check_expired(struct request *rq, unsigned long *next_timeout,
121320ae51fSJens Axboe 			  unsigned int *next_set)
122320ae51fSJens Axboe {
123320ae51fSJens Axboe 	if (time_after_eq(jiffies, rq->deadline)) {
124320ae51fSJens Axboe 		list_del_init(&rq->timeout_list);
125320ae51fSJens Axboe 
126320ae51fSJens Axboe 		/*
127320ae51fSJens Axboe 		 * Check if we raced with end io completion
128320ae51fSJens Axboe 		 */
129320ae51fSJens Axboe 		if (!blk_mark_rq_complete(rq))
130320ae51fSJens Axboe 			blk_rq_timed_out(rq);
131320ae51fSJens Axboe 	} else if (!*next_set || time_after(*next_timeout, rq->deadline)) {
132320ae51fSJens Axboe 		*next_timeout = rq->deadline;
133320ae51fSJens Axboe 		*next_set = 1;
134320ae51fSJens Axboe 	}
135320ae51fSJens Axboe }
136320ae51fSJens Axboe 
137242f9dcbSJens Axboe void blk_rq_timed_out_timer(unsigned long data)
138242f9dcbSJens Axboe {
139242f9dcbSJens Axboe 	struct request_queue *q = (struct request_queue *) data;
140565e411dSmalahal@us.ibm.com 	unsigned long flags, next = 0;
141242f9dcbSJens Axboe 	struct request *rq, *tmp;
142a534dbe9SRichard Kennedy 	int next_set = 0;
143242f9dcbSJens Axboe 
144242f9dcbSJens Axboe 	spin_lock_irqsave(q->queue_lock, flags);
145242f9dcbSJens Axboe 
146320ae51fSJens Axboe 	list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
147320ae51fSJens Axboe 		blk_rq_check_expired(rq, &next, &next_set);
148242f9dcbSJens Axboe 
149a534dbe9SRichard Kennedy 	if (next_set)
1507838c15bSAlan Stern 		mod_timer(&q->timeout, round_jiffies_up(next));
151242f9dcbSJens Axboe 
152242f9dcbSJens Axboe 	spin_unlock_irqrestore(q->queue_lock, flags);
153242f9dcbSJens Axboe }
154242f9dcbSJens Axboe 
155242f9dcbSJens Axboe /**
156242f9dcbSJens Axboe  * blk_abort_request -- Request request recovery for the specified command
157242f9dcbSJens Axboe  * @req:	pointer to the request of interest
158242f9dcbSJens Axboe  *
159242f9dcbSJens Axboe  * This function requests that the block layer start recovery for the
160242f9dcbSJens Axboe  * request by deleting the timer and calling the q's timeout function.
161242f9dcbSJens Axboe  * LLDDs who implement their own error recovery MAY ignore the timeout
162242f9dcbSJens Axboe  * event if they generated blk_abort_req. Must hold queue lock.
163242f9dcbSJens Axboe  */
164242f9dcbSJens Axboe void blk_abort_request(struct request *req)
165242f9dcbSJens Axboe {
1667ba1fbaaSJens Axboe 	if (blk_mark_rq_complete(req))
1677ba1fbaaSJens Axboe 		return;
168242f9dcbSJens Axboe 	blk_delete_timer(req);
169242f9dcbSJens Axboe 	blk_rq_timed_out(req);
170242f9dcbSJens Axboe }
171242f9dcbSJens Axboe EXPORT_SYMBOL_GPL(blk_abort_request);
172242f9dcbSJens Axboe 
173320ae51fSJens Axboe void __blk_add_timer(struct request *req, struct list_head *timeout_list)
174242f9dcbSJens Axboe {
175242f9dcbSJens Axboe 	struct request_queue *q = req->q;
176242f9dcbSJens Axboe 	unsigned long expiry;
177242f9dcbSJens Axboe 
178242f9dcbSJens Axboe 	if (!q->rq_timed_out_fn)
179242f9dcbSJens Axboe 		return;
180242f9dcbSJens Axboe 
181242f9dcbSJens Axboe 	BUG_ON(!list_empty(&req->timeout_list));
182242f9dcbSJens Axboe 
183242f9dcbSJens Axboe 	/*
1842eef33e4STejun Heo 	 * Some LLDs, like scsi, peek at the timeout to prevent a
1852eef33e4STejun Heo 	 * command from being retried forever.
186242f9dcbSJens Axboe 	 */
1872eef33e4STejun Heo 	if (!req->timeout)
188242f9dcbSJens Axboe 		req->timeout = q->rq_timeout;
1892eef33e4STejun Heo 
1902eef33e4STejun Heo 	req->deadline = jiffies + req->timeout;
191320ae51fSJens Axboe 	if (timeout_list)
192320ae51fSJens Axboe 		list_add_tail(&req->timeout_list, timeout_list);
193242f9dcbSJens Axboe 
194242f9dcbSJens Axboe 	/*
195242f9dcbSJens Axboe 	 * If the timer isn't already pending or this timeout is earlier
1967838c15bSAlan Stern 	 * than an existing one, modify the timer. Round up to next nearest
197242f9dcbSJens Axboe 	 * second.
198242f9dcbSJens Axboe 	 */
1997838c15bSAlan Stern 	expiry = round_jiffies_up(req->deadline);
200242f9dcbSJens Axboe 
201242f9dcbSJens Axboe 	if (!timer_pending(&q->timeout) ||
202242f9dcbSJens Axboe 	    time_before(expiry, q->timeout.expires))
203242f9dcbSJens Axboe 		mod_timer(&q->timeout, expiry);
204320ae51fSJens Axboe 
205320ae51fSJens Axboe }
206320ae51fSJens Axboe 
207320ae51fSJens Axboe /**
208320ae51fSJens Axboe  * blk_add_timer - Start timeout timer for a single request
209320ae51fSJens Axboe  * @req:	request that is about to start running.
210320ae51fSJens Axboe  *
211320ae51fSJens Axboe  * Notes:
212320ae51fSJens Axboe  *    Each request has its own timer, and as it is added to the queue, we
213320ae51fSJens Axboe  *    set up the timer. When the request completes, we cancel the timer.
214320ae51fSJens Axboe  */
215320ae51fSJens Axboe void blk_add_timer(struct request *req)
216320ae51fSJens Axboe {
217320ae51fSJens Axboe 	__blk_add_timer(req, &req->q->timeout_list);
218242f9dcbSJens Axboe }
21911914a53SMike Anderson 
220