Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : #ifndef BLK_STAT_H 3 : : #define BLK_STAT_H 4 : : 5 : : #include <linux/kernel.h> 6 : : #include <linux/blkdev.h> 7 : : #include <linux/ktime.h> 8 : : #include <linux/rcupdate.h> 9 : : #include <linux/timer.h> 10 : : 11 : : /** 12 : : * struct blk_stat_callback - Block statistics callback. 13 : : * 14 : : * A &struct blk_stat_callback is associated with a &struct request_queue. While 15 : : * @timer is active, that queue's request completion latencies are sorted into 16 : : * buckets by @bucket_fn and added to a per-cpu buffer, @cpu_stat. When the 17 : : * timer fires, @cpu_stat is flushed to @stat and @timer_fn is invoked. 18 : : */ 19 : : struct blk_stat_callback { 20 : : /* 21 : : * @list: RCU list of callbacks for a &struct request_queue. 22 : : */ 23 : : struct list_head list; 24 : : 25 : : /** 26 : : * @timer: Timer for the next callback invocation. 27 : : */ 28 : : struct timer_list timer; 29 : : 30 : : /** 31 : : * @cpu_stat: Per-cpu statistics buckets. 32 : : */ 33 : : struct blk_rq_stat __percpu *cpu_stat; 34 : : 35 : : /** 36 : : * @bucket_fn: Given a request, returns which statistics bucket it 37 : : * should be accounted under. Return -1 for no bucket for this 38 : : * request. 39 : : */ 40 : : int (*bucket_fn)(const struct request *); 41 : : 42 : : /** 43 : : * @buckets: Number of statistics buckets. 44 : : */ 45 : : unsigned int buckets; 46 : : 47 : : /** 48 : : * @stat: Array of statistics buckets. 49 : : */ 50 : : struct blk_rq_stat *stat; 51 : : 52 : : /** 53 : : * @fn: Callback function. 54 : : */ 55 : : void (*timer_fn)(struct blk_stat_callback *); 56 : : 57 : : /** 58 : : * @data: Private pointer for the user. 59 : : */ 60 : : void *data; 61 : : 62 : : struct rcu_head rcu; 63 : : }; 64 : : 65 : : struct blk_queue_stats *blk_alloc_queue_stats(void); 66 : : void blk_free_queue_stats(struct blk_queue_stats *); 67 : : 68 : : void blk_stat_add(struct request *rq, u64 now); 69 : : 70 : : /* record time/size info in request but not add a callback */ 71 : : void blk_stat_enable_accounting(struct request_queue *q); 72 : : 73 : : /** 74 : : * blk_stat_alloc_callback() - Allocate a block statistics callback. 75 : : * @timer_fn: Timer callback function. 76 : : * @bucket_fn: Bucket callback function. 77 : : * @buckets: Number of statistics buckets. 78 : : * @data: Value for the @data field of the &struct blk_stat_callback. 79 : : * 80 : : * See &struct blk_stat_callback for details on the callback functions. 81 : : * 82 : : * Return: &struct blk_stat_callback on success or NULL on ENOMEM. 83 : : */ 84 : : struct blk_stat_callback * 85 : : blk_stat_alloc_callback(void (*timer_fn)(struct blk_stat_callback *), 86 : : int (*bucket_fn)(const struct request *), 87 : : unsigned int buckets, void *data); 88 : : 89 : : /** 90 : : * blk_stat_add_callback() - Add a block statistics callback to be run on a 91 : : * request queue. 92 : : * @q: The request queue. 93 : : * @cb: The callback. 94 : : * 95 : : * Note that a single &struct blk_stat_callback can only be added to a single 96 : : * &struct request_queue. 97 : : */ 98 : : void blk_stat_add_callback(struct request_queue *q, 99 : : struct blk_stat_callback *cb); 100 : : 101 : : /** 102 : : * blk_stat_remove_callback() - Remove a block statistics callback from a 103 : : * request queue. 104 : : * @q: The request queue. 105 : : * @cb: The callback. 106 : : * 107 : : * When this returns, the callback is not running on any CPUs and will not be 108 : : * called again unless readded. 109 : : */ 110 : : void blk_stat_remove_callback(struct request_queue *q, 111 : : struct blk_stat_callback *cb); 112 : : 113 : : /** 114 : : * blk_stat_free_callback() - Free a block statistics callback. 115 : : * @cb: The callback. 116 : : * 117 : : * @cb may be NULL, in which case this does nothing. If it is not NULL, @cb must 118 : : * not be associated with a request queue. I.e., if it was previously added with 119 : : * blk_stat_add_callback(), it must also have been removed since then with 120 : : * blk_stat_remove_callback(). 121 : : */ 122 : : void blk_stat_free_callback(struct blk_stat_callback *cb); 123 : : 124 : : /** 125 : : * blk_stat_is_active() - Check if a block statistics callback is currently 126 : : * gathering statistics. 127 : : * @cb: The callback. 128 : : */ 129 : : static inline bool blk_stat_is_active(struct blk_stat_callback *cb) 130 : : { 131 : : return timer_pending(&cb->timer); 132 : : } 133 : : 134 : : /** 135 : : * blk_stat_activate_nsecs() - Gather block statistics during a time window in 136 : : * nanoseconds. 137 : : * @cb: The callback. 138 : : * @nsecs: Number of nanoseconds to gather statistics for. 139 : : * 140 : : * The timer callback will be called when the window expires. 141 : : */ 142 : : static inline void blk_stat_activate_nsecs(struct blk_stat_callback *cb, 143 : : u64 nsecs) 144 : : { 145 : : mod_timer(&cb->timer, jiffies + nsecs_to_jiffies(nsecs)); 146 : : } 147 : : 148 : : static inline void blk_stat_deactivate(struct blk_stat_callback *cb) 149 : : { 150 : : del_timer_sync(&cb->timer); 151 : : } 152 : : 153 : : /** 154 : : * blk_stat_activate_msecs() - Gather block statistics during a time window in 155 : : * milliseconds. 156 : : * @cb: The callback. 157 : : * @msecs: Number of milliseconds to gather statistics for. 158 : : * 159 : : * The timer callback will be called when the window expires. 160 : : */ 161 : 0 : static inline void blk_stat_activate_msecs(struct blk_stat_callback *cb, 162 : : unsigned int msecs) 163 : : { 164 : 0 : mod_timer(&cb->timer, jiffies + msecs_to_jiffies(msecs)); 165 : 0 : } 166 : : 167 : : void blk_rq_stat_add(struct blk_rq_stat *, u64); 168 : : void blk_rq_stat_sum(struct blk_rq_stat *, struct blk_rq_stat *); 169 : : void blk_rq_stat_init(struct blk_rq_stat *); 170 : : 171 : : #endif