qemu/include/block/accounting.h
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator block accounting
   3 *
   4 * Copyright (c) 2011 Christoph Hellwig
   5 * Copyright (c) 2015 Igalia, S.L.
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25#ifndef BLOCK_ACCOUNTING_H
  26#define BLOCK_ACCOUNTING_H
  27
  28#include "qemu/timed-average.h"
  29#include "qemu/thread.h"
  30#include "qapi/qapi-builtin-types.h"
  31
  32typedef struct BlockAcctTimedStats BlockAcctTimedStats;
  33typedef struct BlockAcctStats BlockAcctStats;
  34
  35enum BlockAcctType {
  36    BLOCK_ACCT_READ,
  37    BLOCK_ACCT_WRITE,
  38    BLOCK_ACCT_FLUSH,
  39    BLOCK_MAX_IOTYPE,
  40};
  41
  42struct BlockAcctTimedStats {
  43    BlockAcctStats *stats;
  44    TimedAverage latency[BLOCK_MAX_IOTYPE];
  45    unsigned interval_length; /* in seconds */
  46    QSLIST_ENTRY(BlockAcctTimedStats) entries;
  47};
  48
  49typedef struct BlockLatencyHistogram {
  50    /* The following histogram is represented like this:
  51     *
  52     * 5|           *
  53     * 4|           *
  54     * 3| *         *
  55     * 2| *         *    *
  56     * 1| *    *    *    *
  57     *  +------------------
  58     *      10   50   100
  59     *
  60     * BlockLatencyHistogram histogram = {
  61     *     .nbins = 4,
  62     *     .boundaries = {10, 50, 100},
  63     *     .bins = {3, 1, 5, 2},
  64     * };
  65     *
  66     * @boundaries array define histogram intervals as follows:
  67     * [0, boundaries[0]), [boundaries[0], boundaries[1]), ...
  68     * [boundaries[nbins-2], +inf)
  69     *
  70     * So, for example above, histogram intervals are:
  71     * [0, 10), [10, 50), [50, 100), [100, +inf)
  72     */
  73    int nbins;
  74    uint64_t *boundaries; /* @nbins-1 numbers here
  75                             (all boundaries, except 0 and +inf) */
  76    uint64_t *bins;
  77} BlockLatencyHistogram;
  78
  79struct BlockAcctStats {
  80    QemuMutex lock;
  81    uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
  82    uint64_t nr_ops[BLOCK_MAX_IOTYPE];
  83    uint64_t invalid_ops[BLOCK_MAX_IOTYPE];
  84    uint64_t failed_ops[BLOCK_MAX_IOTYPE];
  85    uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
  86    uint64_t merged[BLOCK_MAX_IOTYPE];
  87    int64_t last_access_time_ns;
  88    QSLIST_HEAD(, BlockAcctTimedStats) intervals;
  89    bool account_invalid;
  90    bool account_failed;
  91    BlockLatencyHistogram latency_histogram[BLOCK_MAX_IOTYPE];
  92};
  93
  94typedef struct BlockAcctCookie {
  95    int64_t bytes;
  96    int64_t start_time_ns;
  97    enum BlockAcctType type;
  98} BlockAcctCookie;
  99
 100void block_acct_init(BlockAcctStats *stats);
 101void block_acct_setup(BlockAcctStats *stats, bool account_invalid,
 102                     bool account_failed);
 103void block_acct_cleanup(BlockAcctStats *stats);
 104void block_acct_add_interval(BlockAcctStats *stats, unsigned interval_length);
 105BlockAcctTimedStats *block_acct_interval_next(BlockAcctStats *stats,
 106                                              BlockAcctTimedStats *s);
 107void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
 108                      int64_t bytes, enum BlockAcctType type);
 109void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
 110void block_acct_failed(BlockAcctStats *stats, BlockAcctCookie *cookie);
 111void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type);
 112void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
 113                           int num_requests);
 114int64_t block_acct_idle_time_ns(BlockAcctStats *stats);
 115double block_acct_queue_depth(BlockAcctTimedStats *stats,
 116                              enum BlockAcctType type);
 117int block_latency_histogram_set(BlockAcctStats *stats, enum BlockAcctType type,
 118                                uint64List *boundaries);
 119void block_latency_histograms_clear(BlockAcctStats *stats);
 120
 121#endif
 122