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_NONE = 0,
  37    BLOCK_ACCT_READ,
  38    BLOCK_ACCT_WRITE,
  39    BLOCK_ACCT_FLUSH,
  40    BLOCK_ACCT_UNMAP,
  41    BLOCK_MAX_IOTYPE,
  42};
  43
  44struct BlockAcctTimedStats {
  45    BlockAcctStats *stats;
  46    TimedAverage latency[BLOCK_MAX_IOTYPE];
  47    unsigned interval_length; /* in seconds */
  48    QSLIST_ENTRY(BlockAcctTimedStats) entries;
  49};
  50
  51typedef struct BlockLatencyHistogram {
  52    /* The following histogram is represented like this:
  53     *
  54     * 5|           *
  55     * 4|           *
  56     * 3| *         *
  57     * 2| *         *    *
  58     * 1| *    *    *    *
  59     *  +------------------
  60     *      10   50   100
  61     *
  62     * BlockLatencyHistogram histogram = {
  63     *     .nbins = 4,
  64     *     .boundaries = {10, 50, 100},
  65     *     .bins = {3, 1, 5, 2},
  66     * };
  67     *
  68     * @boundaries array define histogram intervals as follows:
  69     * [0, boundaries[0]), [boundaries[0], boundaries[1]), ...
  70     * [boundaries[nbins-2], +inf)
  71     *
  72     * So, for example above, histogram intervals are:
  73     * [0, 10), [10, 50), [50, 100), [100, +inf)
  74     */
  75    int nbins;
  76    uint64_t *boundaries; /* @nbins-1 numbers here
  77                             (all boundaries, except 0 and +inf) */
  78    uint64_t *bins;
  79} BlockLatencyHistogram;
  80
  81struct BlockAcctStats {
  82    QemuMutex lock;
  83    uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
  84    uint64_t nr_ops[BLOCK_MAX_IOTYPE];
  85    uint64_t invalid_ops[BLOCK_MAX_IOTYPE];
  86    uint64_t failed_ops[BLOCK_MAX_IOTYPE];
  87    uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
  88    uint64_t merged[BLOCK_MAX_IOTYPE];
  89    int64_t last_access_time_ns;
  90    QSLIST_HEAD(, BlockAcctTimedStats) intervals;
  91    bool account_invalid;
  92    bool account_failed;
  93    BlockLatencyHistogram latency_histogram[BLOCK_MAX_IOTYPE];
  94};
  95
  96typedef struct BlockAcctCookie {
  97    int64_t bytes;
  98    int64_t start_time_ns;
  99    enum BlockAcctType type;
 100} BlockAcctCookie;
 101
 102void block_acct_init(BlockAcctStats *stats);
 103void block_acct_setup(BlockAcctStats *stats, bool account_invalid,
 104                     bool account_failed);
 105void block_acct_cleanup(BlockAcctStats *stats);
 106void block_acct_add_interval(BlockAcctStats *stats, unsigned interval_length);
 107BlockAcctTimedStats *block_acct_interval_next(BlockAcctStats *stats,
 108                                              BlockAcctTimedStats *s);
 109void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
 110                      int64_t bytes, enum BlockAcctType type);
 111void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
 112void block_acct_failed(BlockAcctStats *stats, BlockAcctCookie *cookie);
 113void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type);
 114void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
 115                           int num_requests);
 116int64_t block_acct_idle_time_ns(BlockAcctStats *stats);
 117double block_acct_queue_depth(BlockAcctTimedStats *stats,
 118                              enum BlockAcctType type);
 119int block_latency_histogram_set(BlockAcctStats *stats, enum BlockAcctType type,
 120                                uint64List *boundaries);
 121void block_latency_histograms_clear(BlockAcctStats *stats);
 122
 123#endif
 124