Commit 1b870fa5 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

kvm: stats: tell userspace which values are boolean



Some of the statistics values exported by KVM are always only 0 or 1.
It can be useful to export this fact to userspace so that it can track
them specially (for example by polling the value every now and then to
compute a % of time spent in a specific state).

Therefore, add "boolean value" as a new "unit".  While it is not exactly
a unit, it walks and quacks like one.  In particular, using the type
would be wrong because boolean values could be instantaneous or peak
values (e.g. "is the rmap allocated?") or even two-bucket histograms
(e.g. "number of posted vs. non-posted interrupt injections").

Suggested-by: default avatarAmneesh Singh <natto@weirdnatto.in>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 84e7051c
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5657,6 +5657,7 @@ by a string of size ``name_size``.
	#define KVM_STATS_UNIT_BYTES		(0x1 << KVM_STATS_UNIT_SHIFT)
	#define KVM_STATS_UNIT_SECONDS		(0x2 << KVM_STATS_UNIT_SHIFT)
	#define KVM_STATS_UNIT_CYCLES		(0x3 << KVM_STATS_UNIT_SHIFT)
	#define KVM_STATS_UNIT_BOOLEAN		(0x4 << KVM_STATS_UNIT_SHIFT)
	#define KVM_STATS_UNIT_MAX		KVM_STATS_UNIT_CYCLES

	#define KVM_STATS_BASE_SHIFT		8
@@ -5724,6 +5725,11 @@ Bits 4-7 of ``flags`` encode the unit:
    It indicates that the statistics data is used to measure time or latency.
  * ``KVM_STATS_UNIT_CYCLES``
    It indicates that the statistics data is used to measure CPU clock cycles.
  * ``KVM_STATS_UNIT_BOOLEAN``
    It indicates that the statistic will always be either 0 or 1.  Boolean
    statistics of "peak" type will never go back from 1 to 0.  Boolean
    statistics can be linear histograms (with two buckets) but not logarithmic
    histograms.

Bits 8-11 of ``flags``, together with ``exponent``, encode the scale of the
unit:
+1 −1
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
	STATS_DESC_COUNTER(VCPU, directed_yield_successful),
	STATS_DESC_COUNTER(VCPU, preemption_reported),
	STATS_DESC_COUNTER(VCPU, preemption_other),
	STATS_DESC_ICOUNTER(VCPU, guest_mode)
	STATS_DESC_IBOOLEAN(VCPU, guest_mode)
};

const struct kvm_stats_header kvm_vcpu_stats_header = {
+10 −1
Original line number Diff line number Diff line
@@ -1822,6 +1822,15 @@ struct _kvm_stats_desc {
	STATS_DESC_PEAK(SCOPE, name, KVM_STATS_UNIT_NONE,		       \
		KVM_STATS_BASE_POW10, 0)

/* Instantaneous boolean value, read only */
#define STATS_DESC_IBOOLEAN(SCOPE, name)				       \
	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_BOOLEAN,		       \
		KVM_STATS_BASE_POW10, 0)
/* Peak (sticky) boolean value, read/write */
#define STATS_DESC_PBOOLEAN(SCOPE, name)				       \
	STATS_DESC_PEAK(SCOPE, name, KVM_STATS_UNIT_BOOLEAN,		       \
		KVM_STATS_BASE_POW10, 0)

/* Cumulative time in nanosecond */
#define STATS_DESC_TIME_NSEC(SCOPE, name)				       \
	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,	       \
@@ -1853,7 +1862,7 @@ struct _kvm_stats_desc {
			HALT_POLL_HIST_COUNT),				       \
	STATS_DESC_LOGHIST_TIME_NSEC(VCPU_GENERIC, halt_wait_hist,	       \
			HALT_POLL_HIST_COUNT),				       \
	STATS_DESC_ICOUNTER(VCPU_GENERIC, blocking)
	STATS_DESC_IBOOLEAN(VCPU_GENERIC, blocking)

extern struct dentry *kvm_debugfs_dir;

+1 −0
Original line number Diff line number Diff line
@@ -2083,6 +2083,7 @@ struct kvm_stats_header {
#define KVM_STATS_UNIT_BYTES		(0x1 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_SECONDS		(0x2 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_CYCLES		(0x3 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_BOOLEAN		(0x4 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_MAX		KVM_STATS_UNIT_CYCLES

#define KVM_STATS_BASE_SHIFT		8