summaryrefslogtreecommitdiff
path: root/block/accounting.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-03-20 09:51:49 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-03-20 09:51:49 +0000
commit4bdc24fa018901892bb8a5bd1808ebd605f4c64d (patch)
treea8697528cea1222bf38abddf88b5746773adfcea /block/accounting.c
parentc26ef39204f3200efe89470f6b21ac783edadd29 (diff)
parent02e3092db3f9b84ed6aae54e3b71d4dc4196c7eb (diff)
downloadqemu-4bdc24fa018901892bb8a5bd1808ebd605f4c64d.tar.gz
Merge remote-tracking branch 'remotes/ericb/tags/pull-qapi-2018-03-12-v4' into staging
qapi patches for 2018-03-12, 2.12 softfreeze - Marc-André Lureau: 0/4 qapi: generate a literal qobject for introspection - Max Reitz: 0/7 block: Handle null backing link - Daniel P. Berrange: chardev: tcp: postpone TLS work until machine done - Peter Xu: 00/23 QMP: out-of-band (OOB) execution support - Vladimir Sementsov-Ogievskiy: 0/2 block latency histogram - Eric Blake: qapi: Pass '-u' when doing non-silent diff # gpg: Signature made Mon 19 Mar 2018 19:59:04 GMT # gpg: using RSA key A7A16B4A2527436A # gpg: Good signature from "Eric Blake <eblake@redhat.com>" # gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" # gpg: aka "[jpeg image of size 6874]" # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * remotes/ericb/tags/pull-qapi-2018-03-12-v4: (38 commits) qapi: Pass '-u' when doing non-silent diff qapi: add block latency histogram interface block/accounting: introduce latency histogram tests: qmp-test: add oob test tests: qmp-test: verify command batching qmp: add command "x-oob-test" monitor: enable IO thread for (qmp & !mux) typed qmp: isolate responses into io thread qmp: support out-of-band (oob) execution qapi: introduce new cmd option "allow-oob" monitor: send event when command queue full qmp: add new event "command-dropped" monitor: separate QMP parser and dispatcher monitor: let suspend/resume work even with QMPs monitor: let suspend_cnt be thread safe monitor: introduce monitor_qmp_respond() qmp: introduce QMPCapability monitor: allow using IO thread for parsing monitor: let mon_list be tail queue monitor: unify global init ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/accounting.c')
-rw-r--r--block/accounting.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/block/accounting.c b/block/accounting.c
index 87ef5bbfaa..70a3d9a426 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -94,6 +94,94 @@ void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
cookie->type = type;
}
+/* block_latency_histogram_compare_func:
+ * Compare @key with interval [@it[0], @it[1]).
+ * Return: -1 if @key < @it[0]
+ * 0 if @key in [@it[0], @it[1])
+ * +1 if @key >= @it[1]
+ */
+static int block_latency_histogram_compare_func(const void *key, const void *it)
+{
+ uint64_t k = *(uint64_t *)key;
+ uint64_t a = ((uint64_t *)it)[0];
+ uint64_t b = ((uint64_t *)it)[1];
+
+ return k < a ? -1 : (k < b ? 0 : 1);
+}
+
+static void block_latency_histogram_account(BlockLatencyHistogram *hist,
+ int64_t latency_ns)
+{
+ uint64_t *pos;
+
+ if (hist->bins == NULL) {
+ /* histogram disabled */
+ return;
+ }
+
+
+ if (latency_ns < hist->boundaries[0]) {
+ hist->bins[0]++;
+ return;
+ }
+
+ if (latency_ns >= hist->boundaries[hist->nbins - 2]) {
+ hist->bins[hist->nbins - 1]++;
+ return;
+ }
+
+ pos = bsearch(&latency_ns, hist->boundaries, hist->nbins - 2,
+ sizeof(hist->boundaries[0]),
+ block_latency_histogram_compare_func);
+ assert(pos != NULL);
+
+ hist->bins[pos - hist->boundaries + 1]++;
+}
+
+int block_latency_histogram_set(BlockAcctStats *stats, enum BlockAcctType type,
+ uint64List *boundaries)
+{
+ BlockLatencyHistogram *hist = &stats->latency_histogram[type];
+ uint64List *entry;
+ uint64_t *ptr;
+ uint64_t prev = 0;
+ int new_nbins = 1;
+
+ for (entry = boundaries; entry; entry = entry->next) {
+ if (entry->value <= prev) {
+ return -EINVAL;
+ }
+ new_nbins++;
+ prev = entry->value;
+ }
+
+ hist->nbins = new_nbins;
+ g_free(hist->boundaries);
+ hist->boundaries = g_new(uint64_t, hist->nbins - 1);
+ for (entry = boundaries, ptr = hist->boundaries; entry;
+ entry = entry->next, ptr++)
+ {
+ *ptr = entry->value;
+ }
+
+ g_free(hist->bins);
+ hist->bins = g_new0(uint64_t, hist->nbins);
+
+ return 0;
+}
+
+void block_latency_histograms_clear(BlockAcctStats *stats)
+{
+ int i;
+
+ for (i = 0; i < BLOCK_MAX_IOTYPE; i++) {
+ BlockLatencyHistogram *hist = &stats->latency_histogram[i];
+ g_free(hist->bins);
+ g_free(hist->boundaries);
+ memset(hist, 0, sizeof(*hist));
+ }
+}
+
static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
bool failed)
{
@@ -116,6 +204,9 @@ static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
stats->nr_ops[cookie->type]++;
}
+ block_latency_histogram_account(&stats->latency_histogram[cookie->type],
+ latency_ns);
+
if (!failed || stats->account_failed) {
stats->total_time_ns[cookie->type] += latency_ns;
stats->last_access_time_ns = time_ns;