mirror of
https://github.com/libvirt/libvirt.git
synced 2026-09-03 20:53:04 -05:00
qemu: monitor: Extract block latency histogram stats into 'qemuBlockStats'
Extract the 'rd_latency_histogram', 'wr_latency_histogram', 'zone_append_latency_histogram', and 'flush_latency_histogram' stats objects into our internal data. Rather than storing 'boundaries' between bins we store them as start points. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
@@ -1943,6 +1943,26 @@ qemuBlockStatsFinalize(GObject *object)
|
||||
g_free(stats->limits);
|
||||
g_free(stats->timed_stats);
|
||||
|
||||
if (stats->histogram_read) {
|
||||
g_free(stats->histogram_read->bins);
|
||||
g_free(stats->histogram_read);
|
||||
}
|
||||
|
||||
if (stats->histogram_write) {
|
||||
g_free(stats->histogram_write->bins);
|
||||
g_free(stats->histogram_write);
|
||||
}
|
||||
|
||||
if (stats->histogram_zone) {
|
||||
g_free(stats->histogram_zone->bins);
|
||||
g_free(stats->histogram_zone);
|
||||
}
|
||||
|
||||
if (stats->histogram_flush) {
|
||||
g_free(stats->histogram_flush->bins);
|
||||
g_free(stats->histogram_flush);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(qemu_block_stats_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
|
||||
@@ -803,6 +803,18 @@ struct qemuBlockStatsLimits {
|
||||
};
|
||||
|
||||
|
||||
struct qemuBlockStatsLatencyHistogramBin {
|
||||
unsigned long long start;
|
||||
unsigned long long value;
|
||||
};
|
||||
|
||||
|
||||
struct qemuBlockStatsLatencyHistogram {
|
||||
struct qemuBlockStatsLatencyHistogramBin *bins;
|
||||
size_t nbins;
|
||||
};
|
||||
|
||||
|
||||
struct qemuBlockStatsTimed {
|
||||
unsigned long long interval_length;
|
||||
|
||||
@@ -855,6 +867,12 @@ struct _qemuBlockStats {
|
||||
/* block accounting/timed stats from qemu - one entry per interval configured */
|
||||
size_t n_timed_stats;
|
||||
struct qemuBlockStatsTimed *timed_stats;
|
||||
|
||||
/* latency histograms */
|
||||
struct qemuBlockStatsLatencyHistogram *histogram_read;
|
||||
struct qemuBlockStatsLatencyHistogram *histogram_write;
|
||||
struct qemuBlockStatsLatencyHistogram *histogram_zone;
|
||||
struct qemuBlockStatsLatencyHistogram *histogram_flush;
|
||||
};
|
||||
G_DECLARE_FINAL_TYPE(qemuBlockStats, qemu_block_stats, QEMU, BLOCK_STATS, GObject);
|
||||
|
||||
|
||||
@@ -2462,6 +2462,52 @@ qemuMonitorJSONBlockStatsCollectDataTimed(virJSONValue *timed_stats,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(virJSONValue *stats,
|
||||
const char *histogram_field,
|
||||
struct qemuBlockStatsLatencyHistogram **histogram_data)
|
||||
{
|
||||
virJSONValue *hist;
|
||||
virJSONValue *hist_bins;
|
||||
virJSONValue *hist_bounds;
|
||||
g_autofree struct qemuBlockStatsLatencyHistogramBin *bins = NULL;
|
||||
size_t nbins = 0;
|
||||
size_t i;
|
||||
|
||||
if (!(hist = virJSONValueObjectGetObject(stats, histogram_field)))
|
||||
return;
|
||||
|
||||
if (!(hist_bins = virJSONValueObjectGetArray(hist, "bins")) ||
|
||||
!(hist_bounds = virJSONValueObjectGetArray(hist, "boundaries")) ||
|
||||
virJSONValueArraySize(hist_bins) != (virJSONValueArraySize(hist_bounds) + 1)) {
|
||||
VIR_DEBUG("malformed latency histogram container");
|
||||
return;
|
||||
}
|
||||
|
||||
nbins = virJSONValueArraySize(hist_bins);
|
||||
bins = g_new0(struct qemuBlockStatsLatencyHistogramBin, nbins);
|
||||
|
||||
for (i = 0; i < nbins; i++) {
|
||||
virJSONValue *bin = virJSONValueArrayGet(hist_bins, i);
|
||||
virJSONValue *bound = NULL;
|
||||
|
||||
if (i > 0)
|
||||
bound = virJSONValueArrayGet(hist_bounds, i - 1);
|
||||
|
||||
if (!bin ||
|
||||
virJSONValueGetNumberUlong(bin, &(bins[i].value)) < 0 ||
|
||||
(bound && virJSONValueGetNumberUlong(bound, &(bins[i].start)) < 0)) {
|
||||
VIR_DEBUG("malformed latency histogram container");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*histogram_data = g_new0(struct qemuBlockStatsLatencyHistogram, 1);
|
||||
(*histogram_data)->bins = g_steal_pointer(&bins);
|
||||
(*histogram_data)->nbins = nbins;
|
||||
}
|
||||
|
||||
|
||||
static qemuBlockStats *
|
||||
qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev,
|
||||
int *nstats)
|
||||
@@ -2506,6 +2552,15 @@ qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev,
|
||||
bstats->wr_highest_offset_valid = true;
|
||||
}
|
||||
|
||||
qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "rd_latency_histogram",
|
||||
&bstats->histogram_read);
|
||||
qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "wr_latency_histogram",
|
||||
&bstats->histogram_write);
|
||||
qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "zone_append_latency_histogram",
|
||||
&bstats->histogram_zone);
|
||||
qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "flush_latency_histogram",
|
||||
&bstats->histogram_flush);
|
||||
|
||||
if ((timed_stats = virJSONValueObjectGetArray(stats, "timed_stats")) &&
|
||||
virJSONValueArraySize(timed_stats) > 0)
|
||||
qemuMonitorJSONBlockStatsCollectDataTimed(timed_stats, bstats);
|
||||
|
||||
Reference in New Issue
Block a user