forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
4.6 KiB
171 lines
4.6 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
#ifndef BLK_STAT_H |
|
#define BLK_STAT_H |
|
|
|
#include <linux/kernel.h> |
|
#include <linux/blkdev.h> |
|
#include <linux/ktime.h> |
|
#include <linux/rcupdate.h> |
|
#include <linux/timer.h> |
|
|
|
/** |
|
* struct blk_stat_callback - Block statistics callback. |
|
* |
|
* A &struct blk_stat_callback is associated with a &struct request_queue. While |
|
* @timer is active, that queue's request completion latencies are sorted into |
|
* buckets by @bucket_fn and added to a per-cpu buffer, @cpu_stat. When the |
|
* timer fires, @cpu_stat is flushed to @stat and @timer_fn is invoked. |
|
*/ |
|
struct blk_stat_callback { |
|
/* |
|
* @list: RCU list of callbacks for a &struct request_queue. |
|
*/ |
|
struct list_head list; |
|
|
|
/** |
|
* @timer: Timer for the next callback invocation. |
|
*/ |
|
struct timer_list timer; |
|
|
|
/** |
|
* @cpu_stat: Per-cpu statistics buckets. |
|
*/ |
|
struct blk_rq_stat __percpu *cpu_stat; |
|
|
|
/** |
|
* @bucket_fn: Given a request, returns which statistics bucket it |
|
* should be accounted under. Return -1 for no bucket for this |
|
* request. |
|
*/ |
|
int (*bucket_fn)(const struct request *); |
|
|
|
/** |
|
* @buckets: Number of statistics buckets. |
|
*/ |
|
unsigned int buckets; |
|
|
|
/** |
|
* @stat: Array of statistics buckets. |
|
*/ |
|
struct blk_rq_stat *stat; |
|
|
|
/** |
|
* @fn: Callback function. |
|
*/ |
|
void (*timer_fn)(struct blk_stat_callback *); |
|
|
|
/** |
|
* @data: Private pointer for the user. |
|
*/ |
|
void *data; |
|
|
|
struct rcu_head rcu; |
|
}; |
|
|
|
struct blk_queue_stats *blk_alloc_queue_stats(void); |
|
void blk_free_queue_stats(struct blk_queue_stats *); |
|
|
|
void blk_stat_add(struct request *rq, u64 now); |
|
|
|
/* record time/size info in request but not add a callback */ |
|
void blk_stat_enable_accounting(struct request_queue *q); |
|
|
|
/** |
|
* blk_stat_alloc_callback() - Allocate a block statistics callback. |
|
* @timer_fn: Timer callback function. |
|
* @bucket_fn: Bucket callback function. |
|
* @buckets: Number of statistics buckets. |
|
* @data: Value for the @data field of the &struct blk_stat_callback. |
|
* |
|
* See &struct blk_stat_callback for details on the callback functions. |
|
* |
|
* Return: &struct blk_stat_callback on success or NULL on ENOMEM. |
|
*/ |
|
struct blk_stat_callback * |
|
blk_stat_alloc_callback(void (*timer_fn)(struct blk_stat_callback *), |
|
int (*bucket_fn)(const struct request *), |
|
unsigned int buckets, void *data); |
|
|
|
/** |
|
* blk_stat_add_callback() - Add a block statistics callback to be run on a |
|
* request queue. |
|
* @q: The request queue. |
|
* @cb: The callback. |
|
* |
|
* Note that a single &struct blk_stat_callback can only be added to a single |
|
* &struct request_queue. |
|
*/ |
|
void blk_stat_add_callback(struct request_queue *q, |
|
struct blk_stat_callback *cb); |
|
|
|
/** |
|
* blk_stat_remove_callback() - Remove a block statistics callback from a |
|
* request queue. |
|
* @q: The request queue. |
|
* @cb: The callback. |
|
* |
|
* When this returns, the callback is not running on any CPUs and will not be |
|
* called again unless readded. |
|
*/ |
|
void blk_stat_remove_callback(struct request_queue *q, |
|
struct blk_stat_callback *cb); |
|
|
|
/** |
|
* blk_stat_free_callback() - Free a block statistics callback. |
|
* @cb: The callback. |
|
* |
|
* @cb may be NULL, in which case this does nothing. If it is not NULL, @cb must |
|
* not be associated with a request queue. I.e., if it was previously added with |
|
* blk_stat_add_callback(), it must also have been removed since then with |
|
* blk_stat_remove_callback(). |
|
*/ |
|
void blk_stat_free_callback(struct blk_stat_callback *cb); |
|
|
|
/** |
|
* blk_stat_is_active() - Check if a block statistics callback is currently |
|
* gathering statistics. |
|
* @cb: The callback. |
|
*/ |
|
static inline bool blk_stat_is_active(struct blk_stat_callback *cb) |
|
{ |
|
return timer_pending(&cb->timer); |
|
} |
|
|
|
/** |
|
* blk_stat_activate_nsecs() - Gather block statistics during a time window in |
|
* nanoseconds. |
|
* @cb: The callback. |
|
* @nsecs: Number of nanoseconds to gather statistics for. |
|
* |
|
* The timer callback will be called when the window expires. |
|
*/ |
|
static inline void blk_stat_activate_nsecs(struct blk_stat_callback *cb, |
|
u64 nsecs) |
|
{ |
|
mod_timer(&cb->timer, jiffies + nsecs_to_jiffies(nsecs)); |
|
} |
|
|
|
static inline void blk_stat_deactivate(struct blk_stat_callback *cb) |
|
{ |
|
del_timer_sync(&cb->timer); |
|
} |
|
|
|
/** |
|
* blk_stat_activate_msecs() - Gather block statistics during a time window in |
|
* milliseconds. |
|
* @cb: The callback. |
|
* @msecs: Number of milliseconds to gather statistics for. |
|
* |
|
* The timer callback will be called when the window expires. |
|
*/ |
|
static inline void blk_stat_activate_msecs(struct blk_stat_callback *cb, |
|
unsigned int msecs) |
|
{ |
|
mod_timer(&cb->timer, jiffies + msecs_to_jiffies(msecs)); |
|
} |
|
|
|
void blk_rq_stat_add(struct blk_rq_stat *, u64); |
|
void blk_rq_stat_sum(struct blk_rq_stat *, struct blk_rq_stat *); |
|
void blk_rq_stat_init(struct blk_rq_stat *); |
|
|
|
#endif
|
|
|