linux/block/blk-stat.h
<<
>>
Prefs
   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 */
  19struct 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
  65struct blk_queue_stats *blk_alloc_queue_stats(void);
  66void blk_free_queue_stats(struct blk_queue_stats *);
  67
  68void blk_stat_add(struct request *rq, u64 now);
  69
  70/* record time/size info in request but not add a callback */
  71void 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 */
  84struct blk_stat_callback *
  85blk_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 */
  98void 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 */
 110void 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 */
 122void 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 */
 129static 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 */
 142static 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
 148static 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 */
 161static inline void blk_stat_activate_msecs(struct blk_stat_callback *cb,
 162                                           unsigned int msecs)
 163{
 164        mod_timer(&cb->timer, jiffies + msecs_to_jiffies(msecs));
 165}
 166
 167void blk_rq_stat_add(struct blk_rq_stat *, u64);
 168void blk_rq_stat_sum(struct blk_rq_stat *, struct blk_rq_stat *);
 169void blk_rq_stat_init(struct blk_rq_stat *);
 170
 171#endif
 172