root/block/blk-timeout.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_fail_io_timeout
  2. blk_should_fake_timeout
  3. fail_io_timeout_debugfs
  4. part_timeout_show
  5. part_timeout_store
  6. blk_abort_request
  7. blk_rq_timeout
  8. blk_add_timer

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Functions related to generic timeout handling of requests.
   4  */
   5 #include <linux/kernel.h>
   6 #include <linux/module.h>
   7 #include <linux/blkdev.h>
   8 #include <linux/fault-inject.h>
   9 
  10 #include "blk.h"
  11 #include "blk-mq.h"
  12 
  13 #ifdef CONFIG_FAIL_IO_TIMEOUT
  14 
  15 static DECLARE_FAULT_ATTR(fail_io_timeout);
  16 
  17 static int __init setup_fail_io_timeout(char *str)
  18 {
  19         return setup_fault_attr(&fail_io_timeout, str);
  20 }
  21 __setup("fail_io_timeout=", setup_fail_io_timeout);
  22 
  23 int blk_should_fake_timeout(struct request_queue *q)
  24 {
  25         if (!test_bit(QUEUE_FLAG_FAIL_IO, &q->queue_flags))
  26                 return 0;
  27 
  28         return should_fail(&fail_io_timeout, 1);
  29 }
  30 
  31 static int __init fail_io_timeout_debugfs(void)
  32 {
  33         struct dentry *dir = fault_create_debugfs_attr("fail_io_timeout",
  34                                                 NULL, &fail_io_timeout);
  35 
  36         return PTR_ERR_OR_ZERO(dir);
  37 }
  38 
  39 late_initcall(fail_io_timeout_debugfs);
  40 
  41 ssize_t part_timeout_show(struct device *dev, struct device_attribute *attr,
  42                           char *buf)
  43 {
  44         struct gendisk *disk = dev_to_disk(dev);
  45         int set = test_bit(QUEUE_FLAG_FAIL_IO, &disk->queue->queue_flags);
  46 
  47         return sprintf(buf, "%d\n", set != 0);
  48 }
  49 
  50 ssize_t part_timeout_store(struct device *dev, struct device_attribute *attr,
  51                            const char *buf, size_t count)
  52 {
  53         struct gendisk *disk = dev_to_disk(dev);
  54         int val;
  55 
  56         if (count) {
  57                 struct request_queue *q = disk->queue;
  58                 char *p = (char *) buf;
  59 
  60                 val = simple_strtoul(p, &p, 10);
  61                 if (val)
  62                         blk_queue_flag_set(QUEUE_FLAG_FAIL_IO, q);
  63                 else
  64                         blk_queue_flag_clear(QUEUE_FLAG_FAIL_IO, q);
  65         }
  66 
  67         return count;
  68 }
  69 
  70 #endif /* CONFIG_FAIL_IO_TIMEOUT */
  71 
  72 /**
  73  * blk_abort_request -- Request request recovery for the specified command
  74  * @req:        pointer to the request of interest
  75  *
  76  * This function requests that the block layer start recovery for the
  77  * request by deleting the timer and calling the q's timeout function.
  78  * LLDDs who implement their own error recovery MAY ignore the timeout
  79  * event if they generated blk_abort_request.
  80  */
  81 void blk_abort_request(struct request *req)
  82 {
  83         /*
  84          * All we need to ensure is that timeout scan takes place
  85          * immediately and that scan sees the new timeout value.
  86          * No need for fancy synchronizations.
  87          */
  88         WRITE_ONCE(req->deadline, jiffies);
  89         kblockd_schedule_work(&req->q->timeout_work);
  90 }
  91 EXPORT_SYMBOL_GPL(blk_abort_request);
  92 
  93 unsigned long blk_rq_timeout(unsigned long timeout)
  94 {
  95         unsigned long maxt;
  96 
  97         maxt = round_jiffies_up(jiffies + BLK_MAX_TIMEOUT);
  98         if (time_after(timeout, maxt))
  99                 timeout = maxt;
 100 
 101         return timeout;
 102 }
 103 
 104 /**
 105  * blk_add_timer - Start timeout timer for a single request
 106  * @req:        request that is about to start running.
 107  *
 108  * Notes:
 109  *    Each request has its own timer, and as it is added to the queue, we
 110  *    set up the timer. When the request completes, we cancel the timer.
 111  */
 112 void blk_add_timer(struct request *req)
 113 {
 114         struct request_queue *q = req->q;
 115         unsigned long expiry;
 116 
 117         /*
 118          * Some LLDs, like scsi, peek at the timeout to prevent a
 119          * command from being retried forever.
 120          */
 121         if (!req->timeout)
 122                 req->timeout = q->rq_timeout;
 123 
 124         req->rq_flags &= ~RQF_TIMED_OUT;
 125 
 126         expiry = jiffies + req->timeout;
 127         WRITE_ONCE(req->deadline, expiry);
 128 
 129         /*
 130          * If the timer isn't already pending or this timeout is earlier
 131          * than an existing one, modify the timer. Round up to next nearest
 132          * second.
 133          */
 134         expiry = blk_rq_timeout(round_jiffies_up(expiry));
 135 
 136         if (!timer_pending(&q->timeout) ||
 137             time_before(expiry, q->timeout.expires)) {
 138                 unsigned long diff = q->timeout.expires - expiry;
 139 
 140                 /*
 141                  * Due to added timer slack to group timers, the timer
 142                  * will often be a little in front of what we asked for.
 143                  * So apply some tolerance here too, otherwise we keep
 144                  * modifying the timer because expires for value X
 145                  * will be X + something.
 146                  */
 147                 if (!timer_pending(&q->timeout) || (diff >= HZ / 2))
 148                         mod_timer(&q->timeout, expiry);
 149         }
 150 
 151 }

/* [<][>][^][v][top][bottom][index][help] */