mbox series

[v6,0/4] KVM statistics data fd-based binary interface

Message ID 20210524151828.4113777-1-jingzhangos@google.com
Headers show
Series KVM statistics data fd-based binary interface | expand

Message

Jing Zhang May 24, 2021, 3:18 p.m. UTC
This patchset provides a file descriptor for every VM and VCPU to read
KVM statistics data in binary format.
It is meant to provide a lightweight, flexible, scalable and efficient
lock-free solution for user space telemetry applications to pull the
statistics data periodically for large scale systems. The pulling
frequency could be as high as a few times per second.
In this patchset, every statistics data are treated to have some
attributes as below:
  * architecture dependent or common
  * VM statistics data or VCPU statistics data
  * type: cumulative, instantaneous,
  * unit: none for simple counter, nanosecond, microsecond,
    millisecond, second, Byte, KiByte, MiByte, GiByte. Clock Cycles
Since no lock/synchronization is used, the consistency between all
the statistics data is not guaranteed. That means not all statistics
data are read out at the exact same time, since the statistics date
are still being updated by KVM subsystems while they are read out.

---

* v5 -> v6
  - Use designated initializers for STATS_DESC
  - Change KVM_STATS_SCALE... to KVM_STATS_BASE...
  - Use a common function for kvm_[vm|vcpu]_stats_read
  - Fix some documentation errors/missings
  - Use TEST_ASSERT in selftest
  - Use a common function for [vm|vcpu]_stats_test in selftest

* v4 -> v5
  - Rebase to kvm/queue, commit a4345a7cecfb ("Merge tag
    'kvmarm-fixes-5.13-1'")
  - Change maximum stats name length to 48
  - Replace VM_STATS_COMMON/VCPU_STATS_COMMON macros with stats
    descriptor definition macros.
  - Fixed some errors/warnings reported by checkpatch.pl

* v3 -> v4
  - Rebase to kvm/queue, commit 9f242010c3b4 ("KVM: avoid "deadlock"
    between install_new_memslots and MMU notifier")
  - Use C-stype comments in the whole patch
  - Fix wrong count for x86 VCPU stats descriptors
  - Fix KVM stats data size counting and validity check in selftest

* v2 -> v3
  - Rebase to kvm/queue, commit edf408f5257b ("KVM: avoid "deadlock"
    between install_new_memslots and MMU notifier")
  - Resolve some nitpicks about format

* v1 -> v2
  - Use ARRAY_SIZE to count the number of stats descriptors
  - Fix missing `size` field initialization in macro STATS_DESC

[1] https://lore.kernel.org/kvm/20210402224359.2297157-1-jingzhangos@google.com
[2] https://lore.kernel.org/kvm/20210415151741.1607806-1-jingzhangos@google.com
[3] https://lore.kernel.org/kvm/20210423181727.596466-1-jingzhangos@google.com
[4] https://lore.kernel.org/kvm/20210429203740.1935629-1-jingzhangos@google.com
[5] https://lore.kernel.org/kvm/20210517145314.157626-1-jingzhangos@google.com

---

Jing Zhang (4):
  KVM: stats: Separate common stats from architecture specific ones
  KVM: stats: Add fd-based API to read binary stats data
  KVM: stats: Add documentation for statistics data binary interface
  KVM: selftests: Add selftest for KVM statistics data binary interface

 Documentation/virt/kvm/api.rst                | 179 +++++++++++++++
 arch/arm64/include/asm/kvm_host.h             |   9 +-
 arch/arm64/kvm/guest.c                        |  38 ++-
 arch/mips/include/asm/kvm_host.h              |   9 +-
 arch/mips/kvm/mips.c                          |  64 +++++-
 arch/powerpc/include/asm/kvm_host.h           |   9 +-
 arch/powerpc/kvm/book3s.c                     |  64 +++++-
 arch/powerpc/kvm/book3s_hv.c                  |  12 +-
 arch/powerpc/kvm/book3s_pr.c                  |   2 +-
 arch/powerpc/kvm/book3s_pr_papr.c             |   2 +-
 arch/powerpc/kvm/booke.c                      |  59 ++++-
 arch/s390/include/asm/kvm_host.h              |   9 +-
 arch/s390/kvm/kvm-s390.c                      | 129 ++++++++++-
 arch/x86/include/asm/kvm_host.h               |   9 +-
 arch/x86/kvm/x86.c                            |  67 +++++-
 include/linux/kvm_host.h                      | 141 +++++++++++-
 include/linux/kvm_types.h                     |  12 +
 include/uapi/linux/kvm.h                      |  50 ++++
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   3 +
 .../testing/selftests/kvm/include/kvm_util.h  |   3 +
 .../selftests/kvm/kvm_bin_form_stats.c        | 216 ++++++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |  12 +
 virt/kvm/kvm_main.c                           | 179 ++++++++++++++-
 24 files changed, 1188 insertions(+), 90 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/kvm_bin_form_stats.c


base-commit: a4345a7cecfb91ae78cd43d26b0c6a956420761a

Comments

Krish Sadhukhan May 25, 2021, 7:49 p.m. UTC | #1
On 5/24/21 8:18 AM, Jing Zhang wrote:
> Put all common statistics in a separate structure to ease

> statistics handling for the incoming new statistics API.

>

> No functional change intended.

>

> Reviewed-by: David Matlack <dmatlack@google.com>

> Reviewed-by: Ricardo Koller <ricarkol@google.com>

> Signed-off-by: Jing Zhang <jingzhangos@google.com>

> ---

>   arch/arm64/include/asm/kvm_host.h   |  9 ++-------

>   arch/arm64/kvm/guest.c              | 12 ++++++------

>   arch/mips/include/asm/kvm_host.h    |  9 ++-------

>   arch/mips/kvm/mips.c                | 12 ++++++------

>   arch/powerpc/include/asm/kvm_host.h |  9 ++-------

>   arch/powerpc/kvm/book3s.c           | 12 ++++++------

>   arch/powerpc/kvm/book3s_hv.c        | 12 ++++++------

>   arch/powerpc/kvm/book3s_pr.c        |  2 +-

>   arch/powerpc/kvm/book3s_pr_papr.c   |  2 +-

>   arch/powerpc/kvm/booke.c            | 14 +++++++-------

>   arch/s390/include/asm/kvm_host.h    |  9 ++-------

>   arch/s390/kvm/kvm-s390.c            | 12 ++++++------

>   arch/x86/include/asm/kvm_host.h     |  9 ++-------

>   arch/x86/kvm/x86.c                  | 14 +++++++-------

>   include/linux/kvm_host.h            |  9 +++++++--

>   include/linux/kvm_types.h           | 12 ++++++++++++

>   virt/kvm/kvm_main.c                 | 14 +++++++-------

>   17 files changed, 82 insertions(+), 90 deletions(-)

>

> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h

> index 7cd7d5c8c4bc..f3ad7a20b0af 100644

> --- a/arch/arm64/include/asm/kvm_host.h

> +++ b/arch/arm64/include/asm/kvm_host.h

> @@ -556,16 +556,11 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)

>   }

>   

>   struct kvm_vm_stat {

> -	ulong remote_tlb_flush;

> +	struct kvm_vm_stat_common common;

>   };

>   

>   struct kvm_vcpu_stat {

> -	u64 halt_successful_poll;

> -	u64 halt_attempted_poll;

> -	u64 halt_poll_success_ns;

> -	u64 halt_poll_fail_ns;

> -	u64 halt_poll_invalid;

> -	u64 halt_wakeup;

> +	struct kvm_vcpu_stat_common common;

>   	u64 hvc_exit_stat;

>   	u64 wfe_exit_stat;

>   	u64 wfi_exit_stat;

> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c

> index 5cb4a1cd5603..0e41331b0911 100644

> --- a/arch/arm64/kvm/guest.c

> +++ b/arch/arm64/kvm/guest.c

> @@ -29,18 +29,18 @@

>   #include "trace.h"

>   

>   struct kvm_stats_debugfs_item debugfs_entries[] = {

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>   	VCPU_STAT("hvc_exit_stat", hvc_exit_stat),

>   	VCPU_STAT("wfe_exit_stat", wfe_exit_stat),

>   	VCPU_STAT("wfi_exit_stat", wfi_exit_stat),

>   	VCPU_STAT("mmio_exit_user", mmio_exit_user),

>   	VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),

>   	VCPU_STAT("exits", exits),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>   	{ NULL }

>   };

>   

> diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h

> index fca4547d580f..6f610fbcd8d1 100644

> --- a/arch/mips/include/asm/kvm_host.h

> +++ b/arch/mips/include/asm/kvm_host.h

> @@ -109,10 +109,11 @@ static inline bool kvm_is_error_hva(unsigned long addr)

>   }

>   

>   struct kvm_vm_stat {

> -	ulong remote_tlb_flush;

> +	struct kvm_vm_stat_common common;

>   };

>   

>   struct kvm_vcpu_stat {

> +	struct kvm_vcpu_stat_common common;

>   	u64 wait_exits;

>   	u64 cache_exits;

>   	u64 signal_exits;

> @@ -142,12 +143,6 @@ struct kvm_vcpu_stat {

>   #ifdef CONFIG_CPU_LOONGSON64

>   	u64 vz_cpucfg_exits;

>   #endif

> -	u64 halt_successful_poll;

> -	u64 halt_attempted_poll;

> -	u64 halt_poll_success_ns;

> -	u64 halt_poll_fail_ns;

> -	u64 halt_poll_invalid;

> -	u64 halt_wakeup;

>   };

>   

>   struct kvm_arch_memory_slot {

> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c

> index 4d4af97dcc88..f4fc60c05e9c 100644

> --- a/arch/mips/kvm/mips.c

> +++ b/arch/mips/kvm/mips.c

> @@ -68,12 +68,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   #ifdef CONFIG_CPU_LOONGSON64

>   	VCPU_STAT("vz_cpucfg", vz_cpucfg_exits),

>   #endif

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>   	{NULL}

>   };

>   

> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h

> index 1e83359f286b..473d9d0804ff 100644

> --- a/arch/powerpc/include/asm/kvm_host.h

> +++ b/arch/powerpc/include/asm/kvm_host.h

> @@ -80,12 +80,13 @@ struct kvmppc_book3s_shadow_vcpu;

>   struct kvm_nested_guest;

>   

>   struct kvm_vm_stat {

> -	ulong remote_tlb_flush;

> +	struct kvm_vm_stat_common common;

>   	ulong num_2M_pages;

>   	ulong num_1G_pages;

>   };

>   

>   struct kvm_vcpu_stat {

> +	struct kvm_vcpu_stat_common common;

>   	u64 sum_exits;

>   	u64 mmio_exits;

>   	u64 signal_exits;

> @@ -101,14 +102,8 @@ struct kvm_vcpu_stat {

>   	u64 emulated_inst_exits;

>   	u64 dec_exits;

>   	u64 ext_intr_exits;

> -	u64 halt_poll_success_ns;

> -	u64 halt_poll_fail_ns;

>   	u64 halt_wait_ns;

> -	u64 halt_successful_poll;

> -	u64 halt_attempted_poll;

>   	u64 halt_successful_wait;

> -	u64 halt_poll_invalid;

> -	u64 halt_wakeup;

>   	u64 dbell_exits;

>   	u64 gdbell_exits;

>   	u64 ld;

> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c

> index 2b691f4d1f26..bd3a10e1fdaf 100644

> --- a/arch/powerpc/kvm/book3s.c

> +++ b/arch/powerpc/kvm/book3s.c

> @@ -47,14 +47,14 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VCPU_STAT("dec", dec_exits),

>   	VCPU_STAT("ext_intr", ext_intr_exits),

>   	VCPU_STAT("queue_intr", queue_intr),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>   	VCPU_STAT("halt_wait_ns", halt_wait_ns),

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

>   	VCPU_STAT("halt_successful_wait", halt_successful_wait),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>   	VCPU_STAT("pf_storage", pf_storage),

>   	VCPU_STAT("sp_storage", sp_storage),

>   	VCPU_STAT("pf_instruc", pf_instruc),

> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c

> index 28a80d240b76..58e187e03c52 100644

> --- a/arch/powerpc/kvm/book3s_hv.c

> +++ b/arch/powerpc/kvm/book3s_hv.c

> @@ -236,7 +236,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)

>   

>   	waitp = kvm_arch_vcpu_get_wait(vcpu);

>   	if (rcuwait_wake_up(waitp))

> -		++vcpu->stat.halt_wakeup;

> +		++vcpu->stat.common.halt_wakeup;

>   

>   	cpu = READ_ONCE(vcpu->arch.thread_cpu);

>   	if (cpu >= 0 && kvmppc_ipi_thread(cpu))

> @@ -3925,7 +3925,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>   	cur = start_poll = ktime_get();

>   	if (vc->halt_poll_ns) {

>   		ktime_t stop = ktime_add_ns(start_poll, vc->halt_poll_ns);

> -		++vc->runner->stat.halt_attempted_poll;

> +		++vc->runner->stat.common.halt_attempted_poll;

>   

>   		vc->vcore_state = VCORE_POLLING;

>   		spin_unlock(&vc->lock);

> @@ -3942,7 +3942,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>   		vc->vcore_state = VCORE_INACTIVE;

>   

>   		if (!do_sleep) {

> -			++vc->runner->stat.halt_successful_poll;

> +			++vc->runner->stat.common.halt_successful_poll;

>   			goto out;

>   		}

>   	}

> @@ -3954,7 +3954,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>   		do_sleep = 0;

>   		/* If we polled, count this as a successful poll */

>   		if (vc->halt_poll_ns)

> -			++vc->runner->stat.halt_successful_poll;

> +			++vc->runner->stat.common.halt_successful_poll;

>   		goto out;

>   	}

>   

> @@ -3981,13 +3981,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>   			ktime_to_ns(cur) - ktime_to_ns(start_wait);

>   		/* Attribute failed poll time */

>   		if (vc->halt_poll_ns)

> -			vc->runner->stat.halt_poll_fail_ns +=

> +			vc->runner->stat.common.halt_poll_fail_ns +=

>   				ktime_to_ns(start_wait) -

>   				ktime_to_ns(start_poll);

>   	} else {

>   		/* Attribute successful poll time */

>   		if (vc->halt_poll_ns)

> -			vc->runner->stat.halt_poll_success_ns +=

> +			vc->runner->stat.common.halt_poll_success_ns +=

>   				ktime_to_ns(cur) -

>   				ktime_to_ns(start_poll);

>   	}

> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c

> index d7733b07f489..214caa9d9675 100644

> --- a/arch/powerpc/kvm/book3s_pr.c

> +++ b/arch/powerpc/kvm/book3s_pr.c

> @@ -493,7 +493,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)

>   		if (!vcpu->arch.pending_exceptions) {

>   			kvm_vcpu_block(vcpu);

>   			kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> -			vcpu->stat.halt_wakeup++;

> +			vcpu->stat.common.halt_wakeup++;

>   

>   			/* Unset POW bit after we woke up */

>   			msr &= ~MSR_POW;

> diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c

> index 031c8015864a..9384625c8051 100644

> --- a/arch/powerpc/kvm/book3s_pr_papr.c

> +++ b/arch/powerpc/kvm/book3s_pr_papr.c

> @@ -378,7 +378,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)

>   		kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);

>   		kvm_vcpu_block(vcpu);

>   		kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> -		vcpu->stat.halt_wakeup++;

> +		vcpu->stat.common.halt_wakeup++;

>   		return EMULATE_DONE;

>   	case H_LOGICAL_CI_LOAD:

>   		return kvmppc_h_pr_logical_ci_load(vcpu);

> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c

> index 7d5fe43f85c4..07fdd7a1254a 100644

> --- a/arch/powerpc/kvm/booke.c

> +++ b/arch/powerpc/kvm/booke.c

> @@ -49,15 +49,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VCPU_STAT("inst_emu", emulated_inst_exits),

>   	VCPU_STAT("dec", dec_exits),

>   	VCPU_STAT("ext_intr", ext_intr_exits),

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>   	VCPU_STAT("doorbell", dbell_exits),

>   	VCPU_STAT("guest doorbell", gdbell_exits),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> -	VM_STAT("remote_tlb_flush", remote_tlb_flush),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

>   	{ NULL }

>   };

>   

> diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h

> index 8925f3969478..57a20897f3db 100644

> --- a/arch/s390/include/asm/kvm_host.h

> +++ b/arch/s390/include/asm/kvm_host.h

> @@ -361,6 +361,7 @@ struct sie_page {

>   };

>   

>   struct kvm_vcpu_stat {

> +	struct kvm_vcpu_stat_common common;

>   	u64 exit_userspace;

>   	u64 exit_null;

>   	u64 exit_external_request;

> @@ -370,13 +371,7 @@ struct kvm_vcpu_stat {

>   	u64 exit_validity;

>   	u64 exit_instruction;

>   	u64 exit_pei;

> -	u64 halt_successful_poll;

> -	u64 halt_attempted_poll;

> -	u64 halt_poll_invalid;

>   	u64 halt_no_poll_steal;

> -	u64 halt_wakeup;

> -	u64 halt_poll_success_ns;

> -	u64 halt_poll_fail_ns;

>   	u64 instruction_lctl;

>   	u64 instruction_lctlg;

>   	u64 instruction_stctl;

> @@ -755,12 +750,12 @@ struct kvm_vcpu_arch {

>   };

>   

>   struct kvm_vm_stat {

> +	struct kvm_vm_stat_common common;

>   	u64 inject_io;

>   	u64 inject_float_mchk;

>   	u64 inject_pfault_done;

>   	u64 inject_service_signal;

>   	u64 inject_virtio;

> -	u64 remote_tlb_flush;

>   };

>   

>   struct kvm_arch_memory_slot {

> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c

> index 1296fc10f80c..d6bf3372bb10 100644

> --- a/arch/s390/kvm/kvm-s390.c

> +++ b/arch/s390/kvm/kvm-s390.c

> @@ -72,13 +72,13 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VCPU_STAT("exit_program_interruption", exit_program_interruption),

>   	VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),

>   	VCPU_STAT("exit_operation_exception", exit_operation_exception),

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

>   	VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>   	VCPU_STAT("instruction_lctlg", instruction_lctlg),

>   	VCPU_STAT("instruction_lctl", instruction_lctl),

>   	VCPU_STAT("instruction_stctl", instruction_stctl),

> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h

> index 55efbacfc244..5bfd6893fbf6 100644

> --- a/arch/x86/include/asm/kvm_host.h

> +++ b/arch/x86/include/asm/kvm_host.h

> @@ -1127,6 +1127,7 @@ struct kvm_arch {

>   };

>   

>   struct kvm_vm_stat {

> +	struct kvm_vm_stat_common common;

>   	ulong mmu_shadow_zapped;

>   	ulong mmu_pte_write;

>   	ulong mmu_pde_zapped;

> @@ -1134,13 +1135,13 @@ struct kvm_vm_stat {

>   	ulong mmu_recycled;

>   	ulong mmu_cache_miss;

>   	ulong mmu_unsync;

> -	ulong remote_tlb_flush;

>   	ulong lpages;

>   	ulong nx_lpage_splits;

>   	ulong max_mmu_page_hash_collisions;

>   };

>   

>   struct kvm_vcpu_stat {

> +	struct kvm_vcpu_stat_common common;

>   	u64 pf_fixed;

>   	u64 pf_guest;

>   	u64 tlb_flush;

> @@ -1154,10 +1155,6 @@ struct kvm_vcpu_stat {

>   	u64 nmi_window_exits;

>   	u64 l1d_flush;

>   	u64 halt_exits;

> -	u64 halt_successful_poll;

> -	u64 halt_attempted_poll;

> -	u64 halt_poll_invalid;

> -	u64 halt_wakeup;

>   	u64 request_irq_exits;

>   	u64 irq_exits;

>   	u64 host_state_reload;

> @@ -1168,8 +1165,6 @@ struct kvm_vcpu_stat {

>   	u64 irq_injections;

>   	u64 nmi_injections;

>   	u64 req_event;

> -	u64 halt_poll_success_ns;

> -	u64 halt_poll_fail_ns;

>   	u64 nested_run;

>   	u64 directed_yield_attempted;

>   	u64 directed_yield_successful;

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c

> index 9b6bca616929..9a93d80caff6 100644

> --- a/arch/x86/kvm/x86.c

> +++ b/arch/x86/kvm/x86.c

> @@ -226,10 +226,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VCPU_STAT("irq_window", irq_window_exits),

>   	VCPU_STAT("nmi_window", nmi_window_exits),

>   	VCPU_STAT("halt_exits", halt_exits),

> -	VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -	VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -	VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -	VCPU_STAT("halt_wakeup", halt_wakeup),

> +	VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +	VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +	VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +	VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>   	VCPU_STAT("hypercalls", hypercalls),

>   	VCPU_STAT("request_irq", request_irq_exits),

>   	VCPU_STAT("irq_exits", irq_exits),

> @@ -241,8 +241,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VCPU_STAT("nmi_injections", nmi_injections),

>   	VCPU_STAT("req_event", req_event),

>   	VCPU_STAT("l1d_flush", l1d_flush),

> -	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +	VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +	VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>   	VCPU_STAT("nested_run", nested_run),

>   	VCPU_STAT("directed_yield_attempted", directed_yield_attempted),

>   	VCPU_STAT("directed_yield_successful", directed_yield_successful),

> @@ -253,7 +253,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>   	VM_STAT("mmu_recycled", mmu_recycled),

>   	VM_STAT("mmu_cache_miss", mmu_cache_miss),

>   	VM_STAT("mmu_unsync", mmu_unsync),

> -	VM_STAT("remote_tlb_flush", remote_tlb_flush),

> +	VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

>   	VM_STAT("largepages", lpages, .mode = 0444),

>   	VM_STAT("nx_largepages_splitted", nx_lpage_splits, .mode = 0444),

>   	VM_STAT("max_mmu_page_hash_collisions", max_mmu_page_hash_collisions),

> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h

> index 2f34487e21f2..97700e41db3b 100644

> --- a/include/linux/kvm_host.h

> +++ b/include/linux/kvm_host.h

> @@ -1243,10 +1243,15 @@ struct kvm_stats_debugfs_item {

>   #define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \

>   	((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)

>   

> -#define VM_STAT(n, x, ...) 							\

> +#define VM_STAT(n, x, ...)						       \

>   	{ n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }

> -#define VCPU_STAT(n, x, ...)							\

> +#define VCPU_STAT(n, x, ...)						       \

>   	{ n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }

> +#define VM_STAT_COM(n, x, ...)						       \

> +	{ n, offsetof(struct kvm, stat.common.x), KVM_STAT_VM, ## __VA_ARGS__ }

> +#define VCPU_STAT_COM(n, x, ...)					       \

> +	{ n, offsetof(struct kvm_vcpu, stat.common.x),			       \

> +	  KVM_STAT_VCPU, ## __VA_ARGS__ }

>   

>   extern struct kvm_stats_debugfs_item debugfs_entries[];

>   extern struct dentry *kvm_debugfs_dir;

> diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h

> index a7580f69dda0..87eb05ad678b 100644

> --- a/include/linux/kvm_types.h

> +++ b/include/linux/kvm_types.h

> @@ -76,5 +76,17 @@ struct kvm_mmu_memory_cache {

>   };

>   #endif

>   

> +struct kvm_vm_stat_common {



Should this be named as 'kvm_vm_stat_generic' by following the 
convention in kvm_main.c ?  For example, kvm_vm_ioctl_enable_cap()  vs.  
kvm_vm_ioctl_enable_cap_generic().

> +	ulong remote_tlb_flush;

> +};

> +

> +struct kvm_vcpu_stat_common {



Same comment as above.

> +	u64 halt_successful_poll;

> +	u64 halt_attempted_poll;

> +	u64 halt_poll_invalid;

> +	u64 halt_wakeup;

> +	u64 halt_poll_success_ns;

> +	u64 halt_poll_fail_ns;

> +};

>   

>   #endif /* __KVM_TYPES_H__ */

> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c

> index 6b4feb92dc79..34a4cf265297 100644

> --- a/virt/kvm/kvm_main.c

> +++ b/virt/kvm/kvm_main.c

> @@ -330,7 +330,7 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)

>   	 */

>   	if (!kvm_arch_flush_remote_tlb(kvm)

>   	    || kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))

> -		++kvm->stat.remote_tlb_flush;

> +		++kvm->stat.common.remote_tlb_flush;

>   	cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);

>   }

>   EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs);

> @@ -2940,9 +2940,9 @@ static inline void

>   update_halt_poll_stats(struct kvm_vcpu *vcpu, u64 poll_ns, bool waited)

>   {

>   	if (waited)

> -		vcpu->stat.halt_poll_fail_ns += poll_ns;

> +		vcpu->stat.common.halt_poll_fail_ns += poll_ns;

>   	else

> -		vcpu->stat.halt_poll_success_ns += poll_ns;

> +		vcpu->stat.common.halt_poll_success_ns += poll_ns;

>   }

>   

>   /*

> @@ -2960,16 +2960,16 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)

>   	if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {

>   		ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);

>   

> -		++vcpu->stat.halt_attempted_poll;

> +		++vcpu->stat.common.halt_attempted_poll;

>   		do {

>   			/*

>   			 * This sets KVM_REQ_UNHALT if an interrupt

>   			 * arrives.

>   			 */

>   			if (kvm_vcpu_check_block(vcpu) < 0) {

> -				++vcpu->stat.halt_successful_poll;

> +				++vcpu->stat.common.halt_successful_poll;

>   				if (!vcpu_valid_wakeup(vcpu))

> -					++vcpu->stat.halt_poll_invalid;

> +					++vcpu->stat.common.halt_poll_invalid;

>   				goto out;

>   			}

>   			poll_end = cur = ktime_get();

> @@ -3027,7 +3027,7 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)

>   	waitp = kvm_arch_vcpu_get_wait(vcpu);

>   	if (rcuwait_wake_up(waitp)) {

>   		WRITE_ONCE(vcpu->ready, true);

> -		++vcpu->stat.halt_wakeup;

> +		++vcpu->stat.common.halt_wakeup;

>   		return true;

>   	}

>
Jing Zhang May 25, 2021, 9:29 p.m. UTC | #2
Hi Krish,

On Tue, May 25, 2021 at 2:49 PM Krish Sadhukhan
<krish.sadhukhan@oracle.com> wrote:
>

>

> On 5/24/21 8:18 AM, Jing Zhang wrote:

> > Put all common statistics in a separate structure to ease

> > statistics handling for the incoming new statistics API.

> >

> > No functional change intended.

> >

> > Reviewed-by: David Matlack <dmatlack@google.com>

> > Reviewed-by: Ricardo Koller <ricarkol@google.com>

> > Signed-off-by: Jing Zhang <jingzhangos@google.com>

> > ---

> >   arch/arm64/include/asm/kvm_host.h   |  9 ++-------

> >   arch/arm64/kvm/guest.c              | 12 ++++++------

> >   arch/mips/include/asm/kvm_host.h    |  9 ++-------

> >   arch/mips/kvm/mips.c                | 12 ++++++------

> >   arch/powerpc/include/asm/kvm_host.h |  9 ++-------

> >   arch/powerpc/kvm/book3s.c           | 12 ++++++------

> >   arch/powerpc/kvm/book3s_hv.c        | 12 ++++++------

> >   arch/powerpc/kvm/book3s_pr.c        |  2 +-

> >   arch/powerpc/kvm/book3s_pr_papr.c   |  2 +-

> >   arch/powerpc/kvm/booke.c            | 14 +++++++-------

> >   arch/s390/include/asm/kvm_host.h    |  9 ++-------

> >   arch/s390/kvm/kvm-s390.c            | 12 ++++++------

> >   arch/x86/include/asm/kvm_host.h     |  9 ++-------

> >   arch/x86/kvm/x86.c                  | 14 +++++++-------

> >   include/linux/kvm_host.h            |  9 +++++++--

> >   include/linux/kvm_types.h           | 12 ++++++++++++

> >   virt/kvm/kvm_main.c                 | 14 +++++++-------

> >   17 files changed, 82 insertions(+), 90 deletions(-)

> >

> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h

> > index 7cd7d5c8c4bc..f3ad7a20b0af 100644

> > --- a/arch/arm64/include/asm/kvm_host.h

> > +++ b/arch/arm64/include/asm/kvm_host.h

> > @@ -556,16 +556,11 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)

> >   }

> >

> >   struct kvm_vm_stat {

> > -     ulong remote_tlb_flush;

> > +     struct kvm_vm_stat_common common;

> >   };

> >

> >   struct kvm_vcpu_stat {

> > -     u64 halt_successful_poll;

> > -     u64 halt_attempted_poll;

> > -     u64 halt_poll_success_ns;

> > -     u64 halt_poll_fail_ns;

> > -     u64 halt_poll_invalid;

> > -     u64 halt_wakeup;

> > +     struct kvm_vcpu_stat_common common;

> >       u64 hvc_exit_stat;

> >       u64 wfe_exit_stat;

> >       u64 wfi_exit_stat;

> > diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c

> > index 5cb4a1cd5603..0e41331b0911 100644

> > --- a/arch/arm64/kvm/guest.c

> > +++ b/arch/arm64/kvm/guest.c

> > @@ -29,18 +29,18 @@

> >   #include "trace.h"

> >

> >   struct kvm_stats_debugfs_item debugfs_entries[] = {

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >       VCPU_STAT("hvc_exit_stat", hvc_exit_stat),

> >       VCPU_STAT("wfe_exit_stat", wfe_exit_stat),

> >       VCPU_STAT("wfi_exit_stat", wfi_exit_stat),

> >       VCPU_STAT("mmio_exit_user", mmio_exit_user),

> >       VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),

> >       VCPU_STAT("exits", exits),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >       { NULL }

> >   };

> >

> > diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h

> > index fca4547d580f..6f610fbcd8d1 100644

> > --- a/arch/mips/include/asm/kvm_host.h

> > +++ b/arch/mips/include/asm/kvm_host.h

> > @@ -109,10 +109,11 @@ static inline bool kvm_is_error_hva(unsigned long addr)

> >   }

> >

> >   struct kvm_vm_stat {

> > -     ulong remote_tlb_flush;

> > +     struct kvm_vm_stat_common common;

> >   };

> >

> >   struct kvm_vcpu_stat {

> > +     struct kvm_vcpu_stat_common common;

> >       u64 wait_exits;

> >       u64 cache_exits;

> >       u64 signal_exits;

> > @@ -142,12 +143,6 @@ struct kvm_vcpu_stat {

> >   #ifdef CONFIG_CPU_LOONGSON64

> >       u64 vz_cpucfg_exits;

> >   #endif

> > -     u64 halt_successful_poll;

> > -     u64 halt_attempted_poll;

> > -     u64 halt_poll_success_ns;

> > -     u64 halt_poll_fail_ns;

> > -     u64 halt_poll_invalid;

> > -     u64 halt_wakeup;

> >   };

> >

> >   struct kvm_arch_memory_slot {

> > diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c

> > index 4d4af97dcc88..f4fc60c05e9c 100644

> > --- a/arch/mips/kvm/mips.c

> > +++ b/arch/mips/kvm/mips.c

> > @@ -68,12 +68,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >   #ifdef CONFIG_CPU_LOONGSON64

> >       VCPU_STAT("vz_cpucfg", vz_cpucfg_exits),

> >   #endif

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >       {NULL}

> >   };

> >

> > diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h

> > index 1e83359f286b..473d9d0804ff 100644

> > --- a/arch/powerpc/include/asm/kvm_host.h

> > +++ b/arch/powerpc/include/asm/kvm_host.h

> > @@ -80,12 +80,13 @@ struct kvmppc_book3s_shadow_vcpu;

> >   struct kvm_nested_guest;

> >

> >   struct kvm_vm_stat {

> > -     ulong remote_tlb_flush;

> > +     struct kvm_vm_stat_common common;

> >       ulong num_2M_pages;

> >       ulong num_1G_pages;

> >   };

> >

> >   struct kvm_vcpu_stat {

> > +     struct kvm_vcpu_stat_common common;

> >       u64 sum_exits;

> >       u64 mmio_exits;

> >       u64 signal_exits;

> > @@ -101,14 +102,8 @@ struct kvm_vcpu_stat {

> >       u64 emulated_inst_exits;

> >       u64 dec_exits;

> >       u64 ext_intr_exits;

> > -     u64 halt_poll_success_ns;

> > -     u64 halt_poll_fail_ns;

> >       u64 halt_wait_ns;

> > -     u64 halt_successful_poll;

> > -     u64 halt_attempted_poll;

> >       u64 halt_successful_wait;

> > -     u64 halt_poll_invalid;

> > -     u64 halt_wakeup;

> >       u64 dbell_exits;

> >       u64 gdbell_exits;

> >       u64 ld;

> > diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c

> > index 2b691f4d1f26..bd3a10e1fdaf 100644

> > --- a/arch/powerpc/kvm/book3s.c

> > +++ b/arch/powerpc/kvm/book3s.c

> > @@ -47,14 +47,14 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VCPU_STAT("dec", dec_exits),

> >       VCPU_STAT("ext_intr", ext_intr_exits),

> >       VCPU_STAT("queue_intr", queue_intr),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >       VCPU_STAT("halt_wait_ns", halt_wait_ns),

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> >       VCPU_STAT("halt_successful_wait", halt_successful_wait),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >       VCPU_STAT("pf_storage", pf_storage),

> >       VCPU_STAT("sp_storage", sp_storage),

> >       VCPU_STAT("pf_instruc", pf_instruc),

> > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c

> > index 28a80d240b76..58e187e03c52 100644

> > --- a/arch/powerpc/kvm/book3s_hv.c

> > +++ b/arch/powerpc/kvm/book3s_hv.c

> > @@ -236,7 +236,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)

> >

> >       waitp = kvm_arch_vcpu_get_wait(vcpu);

> >       if (rcuwait_wake_up(waitp))

> > -             ++vcpu->stat.halt_wakeup;

> > +             ++vcpu->stat.common.halt_wakeup;

> >

> >       cpu = READ_ONCE(vcpu->arch.thread_cpu);

> >       if (cpu >= 0 && kvmppc_ipi_thread(cpu))

> > @@ -3925,7 +3925,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >       cur = start_poll = ktime_get();

> >       if (vc->halt_poll_ns) {

> >               ktime_t stop = ktime_add_ns(start_poll, vc->halt_poll_ns);

> > -             ++vc->runner->stat.halt_attempted_poll;

> > +             ++vc->runner->stat.common.halt_attempted_poll;

> >

> >               vc->vcore_state = VCORE_POLLING;

> >               spin_unlock(&vc->lock);

> > @@ -3942,7 +3942,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >               vc->vcore_state = VCORE_INACTIVE;

> >

> >               if (!do_sleep) {

> > -                     ++vc->runner->stat.halt_successful_poll;

> > +                     ++vc->runner->stat.common.halt_successful_poll;

> >                       goto out;

> >               }

> >       }

> > @@ -3954,7 +3954,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >               do_sleep = 0;

> >               /* If we polled, count this as a successful poll */

> >               if (vc->halt_poll_ns)

> > -                     ++vc->runner->stat.halt_successful_poll;

> > +                     ++vc->runner->stat.common.halt_successful_poll;

> >               goto out;

> >       }

> >

> > @@ -3981,13 +3981,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >                       ktime_to_ns(cur) - ktime_to_ns(start_wait);

> >               /* Attribute failed poll time */

> >               if (vc->halt_poll_ns)

> > -                     vc->runner->stat.halt_poll_fail_ns +=

> > +                     vc->runner->stat.common.halt_poll_fail_ns +=

> >                               ktime_to_ns(start_wait) -

> >                               ktime_to_ns(start_poll);

> >       } else {

> >               /* Attribute successful poll time */

> >               if (vc->halt_poll_ns)

> > -                     vc->runner->stat.halt_poll_success_ns +=

> > +                     vc->runner->stat.common.halt_poll_success_ns +=

> >                               ktime_to_ns(cur) -

> >                               ktime_to_ns(start_poll);

> >       }

> > diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c

> > index d7733b07f489..214caa9d9675 100644

> > --- a/arch/powerpc/kvm/book3s_pr.c

> > +++ b/arch/powerpc/kvm/book3s_pr.c

> > @@ -493,7 +493,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)

> >               if (!vcpu->arch.pending_exceptions) {

> >                       kvm_vcpu_block(vcpu);

> >                       kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> > -                     vcpu->stat.halt_wakeup++;

> > +                     vcpu->stat.common.halt_wakeup++;

> >

> >                       /* Unset POW bit after we woke up */

> >                       msr &= ~MSR_POW;

> > diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c

> > index 031c8015864a..9384625c8051 100644

> > --- a/arch/powerpc/kvm/book3s_pr_papr.c

> > +++ b/arch/powerpc/kvm/book3s_pr_papr.c

> > @@ -378,7 +378,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)

> >               kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);

> >               kvm_vcpu_block(vcpu);

> >               kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> > -             vcpu->stat.halt_wakeup++;

> > +             vcpu->stat.common.halt_wakeup++;

> >               return EMULATE_DONE;

> >       case H_LOGICAL_CI_LOAD:

> >               return kvmppc_h_pr_logical_ci_load(vcpu);

> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c

> > index 7d5fe43f85c4..07fdd7a1254a 100644

> > --- a/arch/powerpc/kvm/booke.c

> > +++ b/arch/powerpc/kvm/booke.c

> > @@ -49,15 +49,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VCPU_STAT("inst_emu", emulated_inst_exits),

> >       VCPU_STAT("dec", dec_exits),

> >       VCPU_STAT("ext_intr", ext_intr_exits),

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >       VCPU_STAT("doorbell", dbell_exits),

> >       VCPU_STAT("guest doorbell", gdbell_exits),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > -     VM_STAT("remote_tlb_flush", remote_tlb_flush),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

> >       { NULL }

> >   };

> >

> > diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h

> > index 8925f3969478..57a20897f3db 100644

> > --- a/arch/s390/include/asm/kvm_host.h

> > +++ b/arch/s390/include/asm/kvm_host.h

> > @@ -361,6 +361,7 @@ struct sie_page {

> >   };

> >

> >   struct kvm_vcpu_stat {

> > +     struct kvm_vcpu_stat_common common;

> >       u64 exit_userspace;

> >       u64 exit_null;

> >       u64 exit_external_request;

> > @@ -370,13 +371,7 @@ struct kvm_vcpu_stat {

> >       u64 exit_validity;

> >       u64 exit_instruction;

> >       u64 exit_pei;

> > -     u64 halt_successful_poll;

> > -     u64 halt_attempted_poll;

> > -     u64 halt_poll_invalid;

> >       u64 halt_no_poll_steal;

> > -     u64 halt_wakeup;

> > -     u64 halt_poll_success_ns;

> > -     u64 halt_poll_fail_ns;

> >       u64 instruction_lctl;

> >       u64 instruction_lctlg;

> >       u64 instruction_stctl;

> > @@ -755,12 +750,12 @@ struct kvm_vcpu_arch {

> >   };

> >

> >   struct kvm_vm_stat {

> > +     struct kvm_vm_stat_common common;

> >       u64 inject_io;

> >       u64 inject_float_mchk;

> >       u64 inject_pfault_done;

> >       u64 inject_service_signal;

> >       u64 inject_virtio;

> > -     u64 remote_tlb_flush;

> >   };

> >

> >   struct kvm_arch_memory_slot {

> > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c

> > index 1296fc10f80c..d6bf3372bb10 100644

> > --- a/arch/s390/kvm/kvm-s390.c

> > +++ b/arch/s390/kvm/kvm-s390.c

> > @@ -72,13 +72,13 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VCPU_STAT("exit_program_interruption", exit_program_interruption),

> >       VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),

> >       VCPU_STAT("exit_operation_exception", exit_operation_exception),

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> >       VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >       VCPU_STAT("instruction_lctlg", instruction_lctlg),

> >       VCPU_STAT("instruction_lctl", instruction_lctl),

> >       VCPU_STAT("instruction_stctl", instruction_stctl),

> > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h

> > index 55efbacfc244..5bfd6893fbf6 100644

> > --- a/arch/x86/include/asm/kvm_host.h

> > +++ b/arch/x86/include/asm/kvm_host.h

> > @@ -1127,6 +1127,7 @@ struct kvm_arch {

> >   };

> >

> >   struct kvm_vm_stat {

> > +     struct kvm_vm_stat_common common;

> >       ulong mmu_shadow_zapped;

> >       ulong mmu_pte_write;

> >       ulong mmu_pde_zapped;

> > @@ -1134,13 +1135,13 @@ struct kvm_vm_stat {

> >       ulong mmu_recycled;

> >       ulong mmu_cache_miss;

> >       ulong mmu_unsync;

> > -     ulong remote_tlb_flush;

> >       ulong lpages;

> >       ulong nx_lpage_splits;

> >       ulong max_mmu_page_hash_collisions;

> >   };

> >

> >   struct kvm_vcpu_stat {

> > +     struct kvm_vcpu_stat_common common;

> >       u64 pf_fixed;

> >       u64 pf_guest;

> >       u64 tlb_flush;

> > @@ -1154,10 +1155,6 @@ struct kvm_vcpu_stat {

> >       u64 nmi_window_exits;

> >       u64 l1d_flush;

> >       u64 halt_exits;

> > -     u64 halt_successful_poll;

> > -     u64 halt_attempted_poll;

> > -     u64 halt_poll_invalid;

> > -     u64 halt_wakeup;

> >       u64 request_irq_exits;

> >       u64 irq_exits;

> >       u64 host_state_reload;

> > @@ -1168,8 +1165,6 @@ struct kvm_vcpu_stat {

> >       u64 irq_injections;

> >       u64 nmi_injections;

> >       u64 req_event;

> > -     u64 halt_poll_success_ns;

> > -     u64 halt_poll_fail_ns;

> >       u64 nested_run;

> >       u64 directed_yield_attempted;

> >       u64 directed_yield_successful;

> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c

> > index 9b6bca616929..9a93d80caff6 100644

> > --- a/arch/x86/kvm/x86.c

> > +++ b/arch/x86/kvm/x86.c

> > @@ -226,10 +226,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VCPU_STAT("irq_window", irq_window_exits),

> >       VCPU_STAT("nmi_window", nmi_window_exits),

> >       VCPU_STAT("halt_exits", halt_exits),

> > -     VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -     VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -     VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -     VCPU_STAT("halt_wakeup", halt_wakeup),

> > +     VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +     VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +     VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +     VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >       VCPU_STAT("hypercalls", hypercalls),

> >       VCPU_STAT("request_irq", request_irq_exits),

> >       VCPU_STAT("irq_exits", irq_exits),

> > @@ -241,8 +241,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VCPU_STAT("nmi_injections", nmi_injections),

> >       VCPU_STAT("req_event", req_event),

> >       VCPU_STAT("l1d_flush", l1d_flush),

> > -     VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -     VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +     VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +     VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >       VCPU_STAT("nested_run", nested_run),

> >       VCPU_STAT("directed_yield_attempted", directed_yield_attempted),

> >       VCPU_STAT("directed_yield_successful", directed_yield_successful),

> > @@ -253,7 +253,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >       VM_STAT("mmu_recycled", mmu_recycled),

> >       VM_STAT("mmu_cache_miss", mmu_cache_miss),

> >       VM_STAT("mmu_unsync", mmu_unsync),

> > -     VM_STAT("remote_tlb_flush", remote_tlb_flush),

> > +     VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

> >       VM_STAT("largepages", lpages, .mode = 0444),

> >       VM_STAT("nx_largepages_splitted", nx_lpage_splits, .mode = 0444),

> >       VM_STAT("max_mmu_page_hash_collisions", max_mmu_page_hash_collisions),

> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h

> > index 2f34487e21f2..97700e41db3b 100644

> > --- a/include/linux/kvm_host.h

> > +++ b/include/linux/kvm_host.h

> > @@ -1243,10 +1243,15 @@ struct kvm_stats_debugfs_item {

> >   #define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \

> >       ((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)

> >

> > -#define VM_STAT(n, x, ...)                                                   \

> > +#define VM_STAT(n, x, ...)                                                  \

> >       { n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }

> > -#define VCPU_STAT(n, x, ...)                                                 \

> > +#define VCPU_STAT(n, x, ...)                                                \

> >       { n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }

> > +#define VM_STAT_COM(n, x, ...)                                                      \

> > +     { n, offsetof(struct kvm, stat.common.x), KVM_STAT_VM, ## __VA_ARGS__ }

> > +#define VCPU_STAT_COM(n, x, ...)                                            \

> > +     { n, offsetof(struct kvm_vcpu, stat.common.x),                         \

> > +       KVM_STAT_VCPU, ## __VA_ARGS__ }

> >

> >   extern struct kvm_stats_debugfs_item debugfs_entries[];

> >   extern struct dentry *kvm_debugfs_dir;

> > diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h

> > index a7580f69dda0..87eb05ad678b 100644

> > --- a/include/linux/kvm_types.h

> > +++ b/include/linux/kvm_types.h

> > @@ -76,5 +76,17 @@ struct kvm_mmu_memory_cache {

> >   };

> >   #endif

> >

> > +struct kvm_vm_stat_common {

>

>

> Should this be named as 'kvm_vm_stat_generic' by following the

> convention in kvm_main.c ?  For example, kvm_vm_ioctl_enable_cap()  vs.

> kvm_vm_ioctl_enable_cap_generic().

>

Sure. Thanks.
> > +     ulong remote_tlb_flush;

> > +};

> > +

> > +struct kvm_vcpu_stat_common {

>

>

> Same comment as above.

>

> > +     u64 halt_successful_poll;

> > +     u64 halt_attempted_poll;

> > +     u64 halt_poll_invalid;

> > +     u64 halt_wakeup;

> > +     u64 halt_poll_success_ns;

> > +     u64 halt_poll_fail_ns;

> > +};

> >

> >   #endif /* __KVM_TYPES_H__ */

> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c

> > index 6b4feb92dc79..34a4cf265297 100644

> > --- a/virt/kvm/kvm_main.c

> > +++ b/virt/kvm/kvm_main.c

> > @@ -330,7 +330,7 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)

> >        */

> >       if (!kvm_arch_flush_remote_tlb(kvm)

> >           || kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))

> > -             ++kvm->stat.remote_tlb_flush;

> > +             ++kvm->stat.common.remote_tlb_flush;

> >       cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);

> >   }

> >   EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs);

> > @@ -2940,9 +2940,9 @@ static inline void

> >   update_halt_poll_stats(struct kvm_vcpu *vcpu, u64 poll_ns, bool waited)

> >   {

> >       if (waited)

> > -             vcpu->stat.halt_poll_fail_ns += poll_ns;

> > +             vcpu->stat.common.halt_poll_fail_ns += poll_ns;

> >       else

> > -             vcpu->stat.halt_poll_success_ns += poll_ns;

> > +             vcpu->stat.common.halt_poll_success_ns += poll_ns;

> >   }

> >

> >   /*

> > @@ -2960,16 +2960,16 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)

> >       if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {

> >               ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);

> >

> > -             ++vcpu->stat.halt_attempted_poll;

> > +             ++vcpu->stat.common.halt_attempted_poll;

> >               do {

> >                       /*

> >                        * This sets KVM_REQ_UNHALT if an interrupt

> >                        * arrives.

> >                        */

> >                       if (kvm_vcpu_check_block(vcpu) < 0) {

> > -                             ++vcpu->stat.halt_successful_poll;

> > +                             ++vcpu->stat.common.halt_successful_poll;

> >                               if (!vcpu_valid_wakeup(vcpu))

> > -                                     ++vcpu->stat.halt_poll_invalid;

> > +                                     ++vcpu->stat.common.halt_poll_invalid;

> >                               goto out;

> >                       }

> >                       poll_end = cur = ktime_get();

> > @@ -3027,7 +3027,7 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)

> >       waitp = kvm_arch_vcpu_get_wait(vcpu);

> >       if (rcuwait_wake_up(waitp)) {

> >               WRITE_ONCE(vcpu->ready, true);

> > -             ++vcpu->stat.halt_wakeup;

> > +             ++vcpu->stat.common.halt_wakeup;

> >               return true;

> >       }

> >
David Matlack May 25, 2021, 9:35 p.m. UTC | #3
On Mon, May 24, 2021 at 8:18 AM Jing Zhang <jingzhangos@google.com> wrote:
>

> Put all common statistics in a separate structure to ease

> statistics handling for the incoming new statistics API.

>

> No functional change intended.

>

> Reviewed-by: David Matlack <dmatlack@google.com>


FYI I think you only add Reviewed-by tags if they are offered by the
reviewer explicitly [1]. Offering your Reviewed-by tag is similar to
hitting the +1 button on Gerrit.

But in any case, this patch looks good so here's my tag:

Reviewed-by: David Matlack <dmatlack@google.com>


[1] https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html#reviewer-s-statement-of-oversight

> Reviewed-by: Ricardo Koller <ricarkol@google.com>

> Signed-off-by: Jing Zhang <jingzhangos@google.com>

> ---

>  arch/arm64/include/asm/kvm_host.h   |  9 ++-------

>  arch/arm64/kvm/guest.c              | 12 ++++++------

>  arch/mips/include/asm/kvm_host.h    |  9 ++-------

>  arch/mips/kvm/mips.c                | 12 ++++++------

>  arch/powerpc/include/asm/kvm_host.h |  9 ++-------

>  arch/powerpc/kvm/book3s.c           | 12 ++++++------

>  arch/powerpc/kvm/book3s_hv.c        | 12 ++++++------

>  arch/powerpc/kvm/book3s_pr.c        |  2 +-

>  arch/powerpc/kvm/book3s_pr_papr.c   |  2 +-

>  arch/powerpc/kvm/booke.c            | 14 +++++++-------

>  arch/s390/include/asm/kvm_host.h    |  9 ++-------

>  arch/s390/kvm/kvm-s390.c            | 12 ++++++------

>  arch/x86/include/asm/kvm_host.h     |  9 ++-------

>  arch/x86/kvm/x86.c                  | 14 +++++++-------

>  include/linux/kvm_host.h            |  9 +++++++--

>  include/linux/kvm_types.h           | 12 ++++++++++++

>  virt/kvm/kvm_main.c                 | 14 +++++++-------

>  17 files changed, 82 insertions(+), 90 deletions(-)

>

> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h

> index 7cd7d5c8c4bc..f3ad7a20b0af 100644

> --- a/arch/arm64/include/asm/kvm_host.h

> +++ b/arch/arm64/include/asm/kvm_host.h

> @@ -556,16 +556,11 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)

>  }

>

>  struct kvm_vm_stat {

> -       ulong remote_tlb_flush;

> +       struct kvm_vm_stat_common common;

>  };

>

>  struct kvm_vcpu_stat {

> -       u64 halt_successful_poll;

> -       u64 halt_attempted_poll;

> -       u64 halt_poll_success_ns;

> -       u64 halt_poll_fail_ns;

> -       u64 halt_poll_invalid;

> -       u64 halt_wakeup;

> +       struct kvm_vcpu_stat_common common;

>         u64 hvc_exit_stat;

>         u64 wfe_exit_stat;

>         u64 wfi_exit_stat;

> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c

> index 5cb4a1cd5603..0e41331b0911 100644

> --- a/arch/arm64/kvm/guest.c

> +++ b/arch/arm64/kvm/guest.c

> @@ -29,18 +29,18 @@

>  #include "trace.h"

>

>  struct kvm_stats_debugfs_item debugfs_entries[] = {

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>         VCPU_STAT("hvc_exit_stat", hvc_exit_stat),

>         VCPU_STAT("wfe_exit_stat", wfe_exit_stat),

>         VCPU_STAT("wfi_exit_stat", wfi_exit_stat),

>         VCPU_STAT("mmio_exit_user", mmio_exit_user),

>         VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),

>         VCPU_STAT("exits", exits),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>         { NULL }

>  };

>

> diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h

> index fca4547d580f..6f610fbcd8d1 100644

> --- a/arch/mips/include/asm/kvm_host.h

> +++ b/arch/mips/include/asm/kvm_host.h

> @@ -109,10 +109,11 @@ static inline bool kvm_is_error_hva(unsigned long addr)

>  }

>

>  struct kvm_vm_stat {

> -       ulong remote_tlb_flush;

> +       struct kvm_vm_stat_common common;

>  };

>

>  struct kvm_vcpu_stat {

> +       struct kvm_vcpu_stat_common common;

>         u64 wait_exits;

>         u64 cache_exits;

>         u64 signal_exits;

> @@ -142,12 +143,6 @@ struct kvm_vcpu_stat {

>  #ifdef CONFIG_CPU_LOONGSON64

>         u64 vz_cpucfg_exits;

>  #endif

> -       u64 halt_successful_poll;

> -       u64 halt_attempted_poll;

> -       u64 halt_poll_success_ns;

> -       u64 halt_poll_fail_ns;

> -       u64 halt_poll_invalid;

> -       u64 halt_wakeup;

>  };

>

>  struct kvm_arch_memory_slot {

> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c

> index 4d4af97dcc88..f4fc60c05e9c 100644

> --- a/arch/mips/kvm/mips.c

> +++ b/arch/mips/kvm/mips.c

> @@ -68,12 +68,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>  #ifdef CONFIG_CPU_LOONGSON64

>         VCPU_STAT("vz_cpucfg", vz_cpucfg_exits),

>  #endif

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>         {NULL}

>  };

>

> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h

> index 1e83359f286b..473d9d0804ff 100644

> --- a/arch/powerpc/include/asm/kvm_host.h

> +++ b/arch/powerpc/include/asm/kvm_host.h

> @@ -80,12 +80,13 @@ struct kvmppc_book3s_shadow_vcpu;

>  struct kvm_nested_guest;

>

>  struct kvm_vm_stat {

> -       ulong remote_tlb_flush;

> +       struct kvm_vm_stat_common common;

>         ulong num_2M_pages;

>         ulong num_1G_pages;

>  };

>

>  struct kvm_vcpu_stat {

> +       struct kvm_vcpu_stat_common common;

>         u64 sum_exits;

>         u64 mmio_exits;

>         u64 signal_exits;

> @@ -101,14 +102,8 @@ struct kvm_vcpu_stat {

>         u64 emulated_inst_exits;

>         u64 dec_exits;

>         u64 ext_intr_exits;

> -       u64 halt_poll_success_ns;

> -       u64 halt_poll_fail_ns;

>         u64 halt_wait_ns;

> -       u64 halt_successful_poll;

> -       u64 halt_attempted_poll;

>         u64 halt_successful_wait;

> -       u64 halt_poll_invalid;

> -       u64 halt_wakeup;

>         u64 dbell_exits;

>         u64 gdbell_exits;

>         u64 ld;

> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c

> index 2b691f4d1f26..bd3a10e1fdaf 100644

> --- a/arch/powerpc/kvm/book3s.c

> +++ b/arch/powerpc/kvm/book3s.c

> @@ -47,14 +47,14 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VCPU_STAT("dec", dec_exits),

>         VCPU_STAT("ext_intr", ext_intr_exits),

>         VCPU_STAT("queue_intr", queue_intr),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>         VCPU_STAT("halt_wait_ns", halt_wait_ns),

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

>         VCPU_STAT("halt_successful_wait", halt_successful_wait),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>         VCPU_STAT("pf_storage", pf_storage),

>         VCPU_STAT("sp_storage", sp_storage),

>         VCPU_STAT("pf_instruc", pf_instruc),

> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c

> index 28a80d240b76..58e187e03c52 100644

> --- a/arch/powerpc/kvm/book3s_hv.c

> +++ b/arch/powerpc/kvm/book3s_hv.c

> @@ -236,7 +236,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)

>

>         waitp = kvm_arch_vcpu_get_wait(vcpu);

>         if (rcuwait_wake_up(waitp))

> -               ++vcpu->stat.halt_wakeup;

> +               ++vcpu->stat.common.halt_wakeup;

>

>         cpu = READ_ONCE(vcpu->arch.thread_cpu);

>         if (cpu >= 0 && kvmppc_ipi_thread(cpu))

> @@ -3925,7 +3925,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>         cur = start_poll = ktime_get();

>         if (vc->halt_poll_ns) {

>                 ktime_t stop = ktime_add_ns(start_poll, vc->halt_poll_ns);

> -               ++vc->runner->stat.halt_attempted_poll;

> +               ++vc->runner->stat.common.halt_attempted_poll;

>

>                 vc->vcore_state = VCORE_POLLING;

>                 spin_unlock(&vc->lock);

> @@ -3942,7 +3942,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>                 vc->vcore_state = VCORE_INACTIVE;

>

>                 if (!do_sleep) {

> -                       ++vc->runner->stat.halt_successful_poll;

> +                       ++vc->runner->stat.common.halt_successful_poll;

>                         goto out;

>                 }

>         }

> @@ -3954,7 +3954,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>                 do_sleep = 0;

>                 /* If we polled, count this as a successful poll */

>                 if (vc->halt_poll_ns)

> -                       ++vc->runner->stat.halt_successful_poll;

> +                       ++vc->runner->stat.common.halt_successful_poll;

>                 goto out;

>         }

>

> @@ -3981,13 +3981,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

>                         ktime_to_ns(cur) - ktime_to_ns(start_wait);

>                 /* Attribute failed poll time */

>                 if (vc->halt_poll_ns)

> -                       vc->runner->stat.halt_poll_fail_ns +=

> +                       vc->runner->stat.common.halt_poll_fail_ns +=

>                                 ktime_to_ns(start_wait) -

>                                 ktime_to_ns(start_poll);

>         } else {

>                 /* Attribute successful poll time */

>                 if (vc->halt_poll_ns)

> -                       vc->runner->stat.halt_poll_success_ns +=

> +                       vc->runner->stat.common.halt_poll_success_ns +=

>                                 ktime_to_ns(cur) -

>                                 ktime_to_ns(start_poll);

>         }

> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c

> index d7733b07f489..214caa9d9675 100644

> --- a/arch/powerpc/kvm/book3s_pr.c

> +++ b/arch/powerpc/kvm/book3s_pr.c

> @@ -493,7 +493,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)

>                 if (!vcpu->arch.pending_exceptions) {

>                         kvm_vcpu_block(vcpu);

>                         kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> -                       vcpu->stat.halt_wakeup++;

> +                       vcpu->stat.common.halt_wakeup++;

>

>                         /* Unset POW bit after we woke up */

>                         msr &= ~MSR_POW;

> diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c

> index 031c8015864a..9384625c8051 100644

> --- a/arch/powerpc/kvm/book3s_pr_papr.c

> +++ b/arch/powerpc/kvm/book3s_pr_papr.c

> @@ -378,7 +378,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)

>                 kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);

>                 kvm_vcpu_block(vcpu);

>                 kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> -               vcpu->stat.halt_wakeup++;

> +               vcpu->stat.common.halt_wakeup++;

>                 return EMULATE_DONE;

>         case H_LOGICAL_CI_LOAD:

>                 return kvmppc_h_pr_logical_ci_load(vcpu);

> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c

> index 7d5fe43f85c4..07fdd7a1254a 100644

> --- a/arch/powerpc/kvm/booke.c

> +++ b/arch/powerpc/kvm/booke.c

> @@ -49,15 +49,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VCPU_STAT("inst_emu", emulated_inst_exits),

>         VCPU_STAT("dec", dec_exits),

>         VCPU_STAT("ext_intr", ext_intr_exits),

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>         VCPU_STAT("doorbell", dbell_exits),

>         VCPU_STAT("guest doorbell", gdbell_exits),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> -       VM_STAT("remote_tlb_flush", remote_tlb_flush),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

>         { NULL }

>  };

>

> diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h

> index 8925f3969478..57a20897f3db 100644

> --- a/arch/s390/include/asm/kvm_host.h

> +++ b/arch/s390/include/asm/kvm_host.h

> @@ -361,6 +361,7 @@ struct sie_page {

>  };

>

>  struct kvm_vcpu_stat {

> +       struct kvm_vcpu_stat_common common;

>         u64 exit_userspace;

>         u64 exit_null;

>         u64 exit_external_request;

> @@ -370,13 +371,7 @@ struct kvm_vcpu_stat {

>         u64 exit_validity;

>         u64 exit_instruction;

>         u64 exit_pei;

> -       u64 halt_successful_poll;

> -       u64 halt_attempted_poll;

> -       u64 halt_poll_invalid;

>         u64 halt_no_poll_steal;

> -       u64 halt_wakeup;

> -       u64 halt_poll_success_ns;

> -       u64 halt_poll_fail_ns;

>         u64 instruction_lctl;

>         u64 instruction_lctlg;

>         u64 instruction_stctl;

> @@ -755,12 +750,12 @@ struct kvm_vcpu_arch {

>  };

>

>  struct kvm_vm_stat {

> +       struct kvm_vm_stat_common common;

>         u64 inject_io;

>         u64 inject_float_mchk;

>         u64 inject_pfault_done;

>         u64 inject_service_signal;

>         u64 inject_virtio;

> -       u64 remote_tlb_flush;

>  };

>

>  struct kvm_arch_memory_slot {

> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c

> index 1296fc10f80c..d6bf3372bb10 100644

> --- a/arch/s390/kvm/kvm-s390.c

> +++ b/arch/s390/kvm/kvm-s390.c

> @@ -72,13 +72,13 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VCPU_STAT("exit_program_interruption", exit_program_interruption),

>         VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),

>         VCPU_STAT("exit_operation_exception", exit_operation_exception),

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

>         VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>         VCPU_STAT("instruction_lctlg", instruction_lctlg),

>         VCPU_STAT("instruction_lctl", instruction_lctl),

>         VCPU_STAT("instruction_stctl", instruction_stctl),

> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h

> index 55efbacfc244..5bfd6893fbf6 100644

> --- a/arch/x86/include/asm/kvm_host.h

> +++ b/arch/x86/include/asm/kvm_host.h

> @@ -1127,6 +1127,7 @@ struct kvm_arch {

>  };

>

>  struct kvm_vm_stat {

> +       struct kvm_vm_stat_common common;

>         ulong mmu_shadow_zapped;

>         ulong mmu_pte_write;

>         ulong mmu_pde_zapped;

> @@ -1134,13 +1135,13 @@ struct kvm_vm_stat {

>         ulong mmu_recycled;

>         ulong mmu_cache_miss;

>         ulong mmu_unsync;

> -       ulong remote_tlb_flush;

>         ulong lpages;

>         ulong nx_lpage_splits;

>         ulong max_mmu_page_hash_collisions;

>  };

>

>  struct kvm_vcpu_stat {

> +       struct kvm_vcpu_stat_common common;

>         u64 pf_fixed;

>         u64 pf_guest;

>         u64 tlb_flush;

> @@ -1154,10 +1155,6 @@ struct kvm_vcpu_stat {

>         u64 nmi_window_exits;

>         u64 l1d_flush;

>         u64 halt_exits;

> -       u64 halt_successful_poll;

> -       u64 halt_attempted_poll;

> -       u64 halt_poll_invalid;

> -       u64 halt_wakeup;

>         u64 request_irq_exits;

>         u64 irq_exits;

>         u64 host_state_reload;

> @@ -1168,8 +1165,6 @@ struct kvm_vcpu_stat {

>         u64 irq_injections;

>         u64 nmi_injections;

>         u64 req_event;

> -       u64 halt_poll_success_ns;

> -       u64 halt_poll_fail_ns;

>         u64 nested_run;

>         u64 directed_yield_attempted;

>         u64 directed_yield_successful;

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c

> index 9b6bca616929..9a93d80caff6 100644

> --- a/arch/x86/kvm/x86.c

> +++ b/arch/x86/kvm/x86.c

> @@ -226,10 +226,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VCPU_STAT("irq_window", irq_window_exits),

>         VCPU_STAT("nmi_window", nmi_window_exits),

>         VCPU_STAT("halt_exits", halt_exits),

> -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> -       VCPU_STAT("halt_wakeup", halt_wakeup),

> +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

>         VCPU_STAT("hypercalls", hypercalls),

>         VCPU_STAT("request_irq", request_irq_exits),

>         VCPU_STAT("irq_exits", irq_exits),

> @@ -241,8 +241,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VCPU_STAT("nmi_injections", nmi_injections),

>         VCPU_STAT("req_event", req_event),

>         VCPU_STAT("l1d_flush", l1d_flush),

> -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

>         VCPU_STAT("nested_run", nested_run),

>         VCPU_STAT("directed_yield_attempted", directed_yield_attempted),

>         VCPU_STAT("directed_yield_successful", directed_yield_successful),

> @@ -253,7 +253,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

>         VM_STAT("mmu_recycled", mmu_recycled),

>         VM_STAT("mmu_cache_miss", mmu_cache_miss),

>         VM_STAT("mmu_unsync", mmu_unsync),

> -       VM_STAT("remote_tlb_flush", remote_tlb_flush),

> +       VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

>         VM_STAT("largepages", lpages, .mode = 0444),

>         VM_STAT("nx_largepages_splitted", nx_lpage_splits, .mode = 0444),

>         VM_STAT("max_mmu_page_hash_collisions", max_mmu_page_hash_collisions),

> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h

> index 2f34487e21f2..97700e41db3b 100644

> --- a/include/linux/kvm_host.h

> +++ b/include/linux/kvm_host.h

> @@ -1243,10 +1243,15 @@ struct kvm_stats_debugfs_item {

>  #define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \

>         ((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)

>

> -#define VM_STAT(n, x, ...)                                                     \

> +#define VM_STAT(n, x, ...)                                                    \

>         { n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }

> -#define VCPU_STAT(n, x, ...)                                                   \

> +#define VCPU_STAT(n, x, ...)                                                  \

>         { n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }

> +#define VM_STAT_COM(n, x, ...)                                                \

> +       { n, offsetof(struct kvm, stat.common.x), KVM_STAT_VM, ## __VA_ARGS__ }

> +#define VCPU_STAT_COM(n, x, ...)                                              \

> +       { n, offsetof(struct kvm_vcpu, stat.common.x),                         \

> +         KVM_STAT_VCPU, ## __VA_ARGS__ }

>

>  extern struct kvm_stats_debugfs_item debugfs_entries[];

>  extern struct dentry *kvm_debugfs_dir;

> diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h

> index a7580f69dda0..87eb05ad678b 100644

> --- a/include/linux/kvm_types.h

> +++ b/include/linux/kvm_types.h

> @@ -76,5 +76,17 @@ struct kvm_mmu_memory_cache {

>  };

>  #endif

>

> +struct kvm_vm_stat_common {

> +       ulong remote_tlb_flush;

> +};

> +

> +struct kvm_vcpu_stat_common {

> +       u64 halt_successful_poll;

> +       u64 halt_attempted_poll;

> +       u64 halt_poll_invalid;

> +       u64 halt_wakeup;

> +       u64 halt_poll_success_ns;

> +       u64 halt_poll_fail_ns;

> +};

>

>  #endif /* __KVM_TYPES_H__ */

> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c

> index 6b4feb92dc79..34a4cf265297 100644

> --- a/virt/kvm/kvm_main.c

> +++ b/virt/kvm/kvm_main.c

> @@ -330,7 +330,7 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)

>          */

>         if (!kvm_arch_flush_remote_tlb(kvm)

>             || kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))

> -               ++kvm->stat.remote_tlb_flush;

> +               ++kvm->stat.common.remote_tlb_flush;

>         cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);

>  }

>  EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs);

> @@ -2940,9 +2940,9 @@ static inline void

>  update_halt_poll_stats(struct kvm_vcpu *vcpu, u64 poll_ns, bool waited)

>  {

>         if (waited)

> -               vcpu->stat.halt_poll_fail_ns += poll_ns;

> +               vcpu->stat.common.halt_poll_fail_ns += poll_ns;

>         else

> -               vcpu->stat.halt_poll_success_ns += poll_ns;

> +               vcpu->stat.common.halt_poll_success_ns += poll_ns;

>  }

>

>  /*

> @@ -2960,16 +2960,16 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)

>         if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {

>                 ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);

>

> -               ++vcpu->stat.halt_attempted_poll;

> +               ++vcpu->stat.common.halt_attempted_poll;

>                 do {

>                         /*

>                          * This sets KVM_REQ_UNHALT if an interrupt

>                          * arrives.

>                          */

>                         if (kvm_vcpu_check_block(vcpu) < 0) {

> -                               ++vcpu->stat.halt_successful_poll;

> +                               ++vcpu->stat.common.halt_successful_poll;

>                                 if (!vcpu_valid_wakeup(vcpu))

> -                                       ++vcpu->stat.halt_poll_invalid;

> +                                       ++vcpu->stat.common.halt_poll_invalid;

>                                 goto out;

>                         }

>                         poll_end = cur = ktime_get();

> @@ -3027,7 +3027,7 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)

>         waitp = kvm_arch_vcpu_get_wait(vcpu);

>         if (rcuwait_wake_up(waitp)) {

>                 WRITE_ONCE(vcpu->ready, true);

> -               ++vcpu->stat.halt_wakeup;

> +               ++vcpu->stat.common.halt_wakeup;

>                 return true;

>         }

>

> --

> 2.31.1.818.g46aad6cb9e-goog

>
David Matlack May 25, 2021, 10:06 p.m. UTC | #4
On Mon, May 24, 2021 at 8:18 AM Jing Zhang <jingzhangos@google.com> wrote:
>

> Update KVM API documentation for binary statistics.

>

> Reviewed-by: David Matlack <dmatlack@google.com>

> Reviewed-by: Ricardo Koller <ricarkol@google.com>

> Signed-off-by: Jing Zhang <jingzhangos@google.com>


Reviewed-by: David Matlack <dmatlack@google.com>


> ---

>  Documentation/virt/kvm/api.rst | 179 +++++++++++++++++++++++++++++++++

>  1 file changed, 179 insertions(+)

>

> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst

> index 7fcb2fd38f42..5cedddd579b2 100644

> --- a/Documentation/virt/kvm/api.rst

> +++ b/Documentation/virt/kvm/api.rst

> @@ -5034,6 +5034,177 @@ see KVM_XEN_VCPU_SET_ATTR above.

>  The KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST type may not be used

>  with the KVM_XEN_VCPU_GET_ATTR ioctl.

>

> +4.130 KVM_STATS_GETFD

> +---------------------

> +

> +:Capability: KVM_CAP_STATS_BINARY_FD

> +:Architectures: all

> +:Type: vm ioctl, vcpu ioctl

> +:Parameters: none

> +:Returns: statistics file descriptor on success, < 0 on error

> +

> +Errors:

> +

> +  ======     ======================================================

> +  ENOMEM     if the fd could not be created due to lack of memory

> +  EMFILE     if the number of opened files exceeds the limit

> +  ======     ======================================================

> +

> +The file descriptor can be used to read VM/vCPU statistics data in binary

> +format. The file data is organized into three blocks as below:

> ++-------------+

> +|   Header    |

> ++-------------+

> +| Descriptors |

> ++-------------+

> +| Stats Data  |

> ++-------------+

> +

> +The Header block is always at the start of the file. It is only needed to be

> +read one time after a VM boot.


nit: "after a VM boot" is not exactly right. If a VM reboots,
userspace does not need to re-read the header. Perhaps change this to
"for the lifetime of the file descriptor"?

> +It is in the form of ``struct kvm_stats_header`` as below::

> +

> +       #define KVM_STATS_ID_MAXLEN             64

> +

> +       struct kvm_stats_header {

> +               char id[KVM_STATS_ID_MAXLEN];

> +               __u32 name_size;

> +               __u32 count;

> +               __u32 desc_offset;

> +               __u32 data_offset;

> +       };

> +

> +The ``id`` field is identification for the corresponding KVM statistics. For

> +VM statistics, it is in the form of "kvm-{kvm pid}", like "kvm-12345". For

> +VCPU statistics, it is in the form of "kvm-{kvm pid}/vcpu-{vcpu id}", like

> +"kvm-12345/vcpu-12".

> +

> +The ``name_size`` field is the size (byte) of the statistics name string

> +(including trailing '\0') appended to the end of every statistics descriptor.

> +

> +The ``count`` field is the number of statistics.

> +

> +The ``desc_offset`` field is the offset of the Descriptors block from the start

> +of the file indicated by the file descriptor.

> +

> +The ``data_offset`` field is the offset of the Stats Data block from the start

> +of the file indicated by the file descriptor.

> +

> +The Descriptors block is only needed to be read once after a VM boot. It is


Ditto here.

> +an array of ``struct kvm_stats_desc`` as shown in below code block::

> +

> +       #define KVM_STATS_TYPE_SHIFT            0

> +       #define KVM_STATS_TYPE_MASK             (0xF << KVM_STATS_TYPE_SHIFT)

> +       #define KVM_STATS_TYPE_CUMULATIVE       (0x0 << KVM_STATS_TYPE_SHIFT)

> +       #define KVM_STATS_TYPE_INSTANT          (0x1 << KVM_STATS_TYPE_SHIFT)

> +       #define KVM_STATS_TYPE_MAX              KVM_STATS_TYPE_INSTANT

> +

> +       #define KVM_STATS_UNIT_SHIFT            4

> +       #define KVM_STATS_UNIT_MASK             (0xF << KVM_STATS_UNIT_SHIFT)

> +       #define KVM_STATS_UNIT_NONE             (0x0 << KVM_STATS_UNIT_SHIFT)

> +       #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_MAX              KVM_STATS_UNIT_CYCLES

> +

> +       #define KVM_STATS_BASE_SHIFT            8

> +       #define KVM_STATS_BASE_MASK             (0xF << KVM_STATS_BASE_SHIFT)

> +       #define KVM_STATS_BASE_POW10            (0x0 << KVM_STATS_BASE_SHIFT)

> +       #define KVM_STATS_BASE_POW2             (0x1 << KVM_STATS_BASE_SHIFT)

> +       #define KVM_STATS_BASE_MAX              KVM_STATS_BASE_POW2

> +

> +       struct kvm_stats_desc {

> +               __u32 flags;

> +               __s16 exponent;

> +               __u16 size;

> +               __u32 unused1;

> +               __u32 unused2;

> +               char name[0];

> +       };

> +

> +The ``flags`` field contains the type and unit of the statistics data described

> +by this descriptor. The following flags are supported:

> +

> +Bits 0-3 of ``flags`` encode the type:

> +  * ``KVM_STATS_TYPE_CUMULATIVE``

> +    The statistics data is cumulative. The value of data can only be increased.

> +    Most of the counters used in KVM are of this type.

> +    The corresponding ``count`` filed for this type is always 1.

> +  * ``KVM_STATS_TYPE_INSTANT``

> +    The statistics data is instantaneous. Its value can be increased or

> +    decreased. This type is usually used as a measurement of some resources,

> +    like the number of dirty pages, the number of large pages, etc.

> +    The corresponding ``count`` field for this type is always 1.

> +

> +Bits 4-7 of ``flags`` encode the unit:

> +  * ``KVM_STATS_UNIT_NONE``

> +    There is no unit for the value of statistics data. This usually means that

> +    the value is a simple counter of an event.

> +  * ``KVM_STATS_UNIT_BYTES``

> +    It indicates that the statistics data is used to measure memory size, in the

> +    unit of Byte, KiByte, MiByte, GiByte, etc. The unit of the data is

> +    determined by the ``exponent`` field in the descriptor. The

> +    ``KVM_STATS_BASE_POW2`` flag is valid in this case. The unit of the data is

> +    determined by ``pow(2, exponent)``. For example, if value is 10,

> +    ``exponent`` is 20, which means the unit of statistics data is MiByte, we

> +    can get the statistics data in the unit of Byte by

> +    ``value * pow(2, exponent) = 10 * pow(2, 20) = 10 MiByte`` which is

> +    10 * 1024 * 1024 Bytes.

> +  * ``KVM_STATS_UNIT_SECONDS``

> +    It indicates that the statistics data is used to measure time/latency, in

> +    the unit of nanosecond, microsecond, millisecond and second. The unit of the

> +    data is determined by the ``exponent`` field in the descriptor. The

> +    ``KVM_STATS_BASE_POW10`` flag is valid in this case. The unit of the data

> +    is determined by ``pow(10, exponent)``. For example, if value is 2000000,

> +    ``exponent`` is -6, which means the unit of statistics data is microsecond,

> +    we can get the statistics data in the unit of second by

> +    ``value * pow(10, exponent) = 2000000 * pow(10, -6) = 2 seconds``.

> +  * ``KVM_STATS_UNIT_CYCLES``

> +    It indicates that the statistics data is used to measure CPU clock cycles.

> +    The ``KVM_STATS_BASE_POW10`` flag is valid in this case. For example, if

> +    value is 200, ``exponent`` is 4, we can get the number of CPU clock cycles

> +    by ``value * pow(10, exponent) = 200 * pow(10, 4) = 2000000``.

> +

> +Bits 7-11 of ``flags`` encode the base:

> +  * ``KVM_STATS_BASE_POW10``

> +    The scale is based on power of 10. It is used for measurement of time and

> +    CPU clock cycles.

> +  * ``KVM_STATS_BASE_POW2``

> +    The scale is based on power of 2. It is used for measurement of memory size.

> +

> +The ``exponent`` field is the scale of corresponding statistics data. For

> +example, if the unit is ``KVM_STATS_UNIT_BYTES``, the base is

> +``KVM_STATS_BASE_POW2``, the ``exponent`` is 10, then we know that the real

> +unit of the statistics data is KBytes a.k.a pow(2, 10) = 1024 bytes.

> +

> +The ``size`` field is the number of values of this statistics data. It is in the

> +unit of ``unsigned long`` for VM or ``__u64`` for VCPU.

> +

> +The ``unused1`` and ``unused2`` fields are reserved for future

> +support for other types of statistics data, like log/linear histogram.

> +

> +The ``name`` field points to the name string of the statistics data. The name

> +string starts at the end of ``struct kvm_stats_desc``.

> +The maximum length (including trailing '\0') is indicated by ``name_size``

> +in ``struct kvm_stats_header``.

> +

> +The Stats Data block contains an array of data values of type ``struct

> +kvm_vm_stats_data`` or ``struct kvm_vcpu_stats_data``. It would be read by

> +user space periodically to pull statistics data.

> +The order of data value in Stats Data block is the same as the order of

> +descriptors in Descriptors block.

> +  * Statistics data for VM::

> +

> +       struct kvm_vm_stats_data {

> +               unsigned long value[0];

> +       };

> +

> +  * Statistics data for VCPU::

> +

> +       struct kvm_vcpu_stats_data {

> +               __u64 value[0];

> +       };

> +

>  5. The kvm_run structure

>  ========================

>

> @@ -6891,3 +7062,11 @@ This capability is always enabled.

>  This capability indicates that the KVM virtual PTP service is

>  supported in the host. A VMM can check whether the service is

>  available to the guest on migration.

> +

> +8.33 KVM_CAP_STATS_BINARY_FD

> +----------------------------

> +

> +:Architectures: all

> +

> +This capability indicates the feature that user space can create get a file

> +descriptor for every VM and VCPU to read statistics data in binary format.

> --

> 2.31.1.818.g46aad6cb9e-goog

>
Jing Zhang May 26, 2021, 5:57 p.m. UTC | #5
On Tue, May 25, 2021 at 4:36 PM David Matlack <dmatlack@google.com> wrote:
>

> On Mon, May 24, 2021 at 8:18 AM Jing Zhang <jingzhangos@google.com> wrote:

> >

> > Put all common statistics in a separate structure to ease

> > statistics handling for the incoming new statistics API.

> >

> > No functional change intended.

> >

> > Reviewed-by: David Matlack <dmatlack@google.com>

>

> FYI I think you only add Reviewed-by tags if they are offered by the

> reviewer explicitly [1]. Offering your Reviewed-by tag is similar to

> hitting the +1 button on Gerrit.

>

> But in any case, this patch looks good so here's my tag:

>

> Reviewed-by: David Matlack <dmatlack@google.com>

>

> [1] https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html#reviewer-s-statement-of-oversight

>

> > Reviewed-by: Ricardo Koller <ricarkol@google.com>

> > Signed-off-by: Jing Zhang <jingzhangos@google.com>

> > ---

> >  arch/arm64/include/asm/kvm_host.h   |  9 ++-------

> >  arch/arm64/kvm/guest.c              | 12 ++++++------

> >  arch/mips/include/asm/kvm_host.h    |  9 ++-------

> >  arch/mips/kvm/mips.c                | 12 ++++++------

> >  arch/powerpc/include/asm/kvm_host.h |  9 ++-------

> >  arch/powerpc/kvm/book3s.c           | 12 ++++++------

> >  arch/powerpc/kvm/book3s_hv.c        | 12 ++++++------

> >  arch/powerpc/kvm/book3s_pr.c        |  2 +-

> >  arch/powerpc/kvm/book3s_pr_papr.c   |  2 +-

> >  arch/powerpc/kvm/booke.c            | 14 +++++++-------

> >  arch/s390/include/asm/kvm_host.h    |  9 ++-------

> >  arch/s390/kvm/kvm-s390.c            | 12 ++++++------

> >  arch/x86/include/asm/kvm_host.h     |  9 ++-------

> >  arch/x86/kvm/x86.c                  | 14 +++++++-------

> >  include/linux/kvm_host.h            |  9 +++++++--

> >  include/linux/kvm_types.h           | 12 ++++++++++++

> >  virt/kvm/kvm_main.c                 | 14 +++++++-------

> >  17 files changed, 82 insertions(+), 90 deletions(-)

> >

> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h

> > index 7cd7d5c8c4bc..f3ad7a20b0af 100644

> > --- a/arch/arm64/include/asm/kvm_host.h

> > +++ b/arch/arm64/include/asm/kvm_host.h

> > @@ -556,16 +556,11 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)

> >  }

> >

> >  struct kvm_vm_stat {

> > -       ulong remote_tlb_flush;

> > +       struct kvm_vm_stat_common common;

> >  };

> >

> >  struct kvm_vcpu_stat {

> > -       u64 halt_successful_poll;

> > -       u64 halt_attempted_poll;

> > -       u64 halt_poll_success_ns;

> > -       u64 halt_poll_fail_ns;

> > -       u64 halt_poll_invalid;

> > -       u64 halt_wakeup;

> > +       struct kvm_vcpu_stat_common common;

> >         u64 hvc_exit_stat;

> >         u64 wfe_exit_stat;

> >         u64 wfi_exit_stat;

> > diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c

> > index 5cb4a1cd5603..0e41331b0911 100644

> > --- a/arch/arm64/kvm/guest.c

> > +++ b/arch/arm64/kvm/guest.c

> > @@ -29,18 +29,18 @@

> >  #include "trace.h"

> >

> >  struct kvm_stats_debugfs_item debugfs_entries[] = {

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >         VCPU_STAT("hvc_exit_stat", hvc_exit_stat),

> >         VCPU_STAT("wfe_exit_stat", wfe_exit_stat),

> >         VCPU_STAT("wfi_exit_stat", wfi_exit_stat),

> >         VCPU_STAT("mmio_exit_user", mmio_exit_user),

> >         VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),

> >         VCPU_STAT("exits", exits),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >         { NULL }

> >  };

> >

> > diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h

> > index fca4547d580f..6f610fbcd8d1 100644

> > --- a/arch/mips/include/asm/kvm_host.h

> > +++ b/arch/mips/include/asm/kvm_host.h

> > @@ -109,10 +109,11 @@ static inline bool kvm_is_error_hva(unsigned long addr)

> >  }

> >

> >  struct kvm_vm_stat {

> > -       ulong remote_tlb_flush;

> > +       struct kvm_vm_stat_common common;

> >  };

> >

> >  struct kvm_vcpu_stat {

> > +       struct kvm_vcpu_stat_common common;

> >         u64 wait_exits;

> >         u64 cache_exits;

> >         u64 signal_exits;

> > @@ -142,12 +143,6 @@ struct kvm_vcpu_stat {

> >  #ifdef CONFIG_CPU_LOONGSON64

> >         u64 vz_cpucfg_exits;

> >  #endif

> > -       u64 halt_successful_poll;

> > -       u64 halt_attempted_poll;

> > -       u64 halt_poll_success_ns;

> > -       u64 halt_poll_fail_ns;

> > -       u64 halt_poll_invalid;

> > -       u64 halt_wakeup;

> >  };

> >

> >  struct kvm_arch_memory_slot {

> > diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c

> > index 4d4af97dcc88..f4fc60c05e9c 100644

> > --- a/arch/mips/kvm/mips.c

> > +++ b/arch/mips/kvm/mips.c

> > @@ -68,12 +68,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >  #ifdef CONFIG_CPU_LOONGSON64

> >         VCPU_STAT("vz_cpucfg", vz_cpucfg_exits),

> >  #endif

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >         {NULL}

> >  };

> >

> > diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h

> > index 1e83359f286b..473d9d0804ff 100644

> > --- a/arch/powerpc/include/asm/kvm_host.h

> > +++ b/arch/powerpc/include/asm/kvm_host.h

> > @@ -80,12 +80,13 @@ struct kvmppc_book3s_shadow_vcpu;

> >  struct kvm_nested_guest;

> >

> >  struct kvm_vm_stat {

> > -       ulong remote_tlb_flush;

> > +       struct kvm_vm_stat_common common;

> >         ulong num_2M_pages;

> >         ulong num_1G_pages;

> >  };

> >

> >  struct kvm_vcpu_stat {

> > +       struct kvm_vcpu_stat_common common;

> >         u64 sum_exits;

> >         u64 mmio_exits;

> >         u64 signal_exits;

> > @@ -101,14 +102,8 @@ struct kvm_vcpu_stat {

> >         u64 emulated_inst_exits;

> >         u64 dec_exits;

> >         u64 ext_intr_exits;

> > -       u64 halt_poll_success_ns;

> > -       u64 halt_poll_fail_ns;

> >         u64 halt_wait_ns;

> > -       u64 halt_successful_poll;

> > -       u64 halt_attempted_poll;

> >         u64 halt_successful_wait;

> > -       u64 halt_poll_invalid;

> > -       u64 halt_wakeup;

> >         u64 dbell_exits;

> >         u64 gdbell_exits;

> >         u64 ld;

> > diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c

> > index 2b691f4d1f26..bd3a10e1fdaf 100644

> > --- a/arch/powerpc/kvm/book3s.c

> > +++ b/arch/powerpc/kvm/book3s.c

> > @@ -47,14 +47,14 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VCPU_STAT("dec", dec_exits),

> >         VCPU_STAT("ext_intr", ext_intr_exits),

> >         VCPU_STAT("queue_intr", queue_intr),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >         VCPU_STAT("halt_wait_ns", halt_wait_ns),

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> >         VCPU_STAT("halt_successful_wait", halt_successful_wait),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >         VCPU_STAT("pf_storage", pf_storage),

> >         VCPU_STAT("sp_storage", sp_storage),

> >         VCPU_STAT("pf_instruc", pf_instruc),

> > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c

> > index 28a80d240b76..58e187e03c52 100644

> > --- a/arch/powerpc/kvm/book3s_hv.c

> > +++ b/arch/powerpc/kvm/book3s_hv.c

> > @@ -236,7 +236,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)

> >

> >         waitp = kvm_arch_vcpu_get_wait(vcpu);

> >         if (rcuwait_wake_up(waitp))

> > -               ++vcpu->stat.halt_wakeup;

> > +               ++vcpu->stat.common.halt_wakeup;

> >

> >         cpu = READ_ONCE(vcpu->arch.thread_cpu);

> >         if (cpu >= 0 && kvmppc_ipi_thread(cpu))

> > @@ -3925,7 +3925,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >         cur = start_poll = ktime_get();

> >         if (vc->halt_poll_ns) {

> >                 ktime_t stop = ktime_add_ns(start_poll, vc->halt_poll_ns);

> > -               ++vc->runner->stat.halt_attempted_poll;

> > +               ++vc->runner->stat.common.halt_attempted_poll;

> >

> >                 vc->vcore_state = VCORE_POLLING;

> >                 spin_unlock(&vc->lock);

> > @@ -3942,7 +3942,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >                 vc->vcore_state = VCORE_INACTIVE;

> >

> >                 if (!do_sleep) {

> > -                       ++vc->runner->stat.halt_successful_poll;

> > +                       ++vc->runner->stat.common.halt_successful_poll;

> >                         goto out;

> >                 }

> >         }

> > @@ -3954,7 +3954,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >                 do_sleep = 0;

> >                 /* If we polled, count this as a successful poll */

> >                 if (vc->halt_poll_ns)

> > -                       ++vc->runner->stat.halt_successful_poll;

> > +                       ++vc->runner->stat.common.halt_successful_poll;

> >                 goto out;

> >         }

> >

> > @@ -3981,13 +3981,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)

> >                         ktime_to_ns(cur) - ktime_to_ns(start_wait);

> >                 /* Attribute failed poll time */

> >                 if (vc->halt_poll_ns)

> > -                       vc->runner->stat.halt_poll_fail_ns +=

> > +                       vc->runner->stat.common.halt_poll_fail_ns +=

> >                                 ktime_to_ns(start_wait) -

> >                                 ktime_to_ns(start_poll);

> >         } else {

> >                 /* Attribute successful poll time */

> >                 if (vc->halt_poll_ns)

> > -                       vc->runner->stat.halt_poll_success_ns +=

> > +                       vc->runner->stat.common.halt_poll_success_ns +=

> >                                 ktime_to_ns(cur) -

> >                                 ktime_to_ns(start_poll);

> >         }

> > diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c

> > index d7733b07f489..214caa9d9675 100644

> > --- a/arch/powerpc/kvm/book3s_pr.c

> > +++ b/arch/powerpc/kvm/book3s_pr.c

> > @@ -493,7 +493,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)

> >                 if (!vcpu->arch.pending_exceptions) {

> >                         kvm_vcpu_block(vcpu);

> >                         kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> > -                       vcpu->stat.halt_wakeup++;

> > +                       vcpu->stat.common.halt_wakeup++;

> >

> >                         /* Unset POW bit after we woke up */

> >                         msr &= ~MSR_POW;

> > diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c

> > index 031c8015864a..9384625c8051 100644

> > --- a/arch/powerpc/kvm/book3s_pr_papr.c

> > +++ b/arch/powerpc/kvm/book3s_pr_papr.c

> > @@ -378,7 +378,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)

> >                 kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);

> >                 kvm_vcpu_block(vcpu);

> >                 kvm_clear_request(KVM_REQ_UNHALT, vcpu);

> > -               vcpu->stat.halt_wakeup++;

> > +               vcpu->stat.common.halt_wakeup++;

> >                 return EMULATE_DONE;

> >         case H_LOGICAL_CI_LOAD:

> >                 return kvmppc_h_pr_logical_ci_load(vcpu);

> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c

> > index 7d5fe43f85c4..07fdd7a1254a 100644

> > --- a/arch/powerpc/kvm/booke.c

> > +++ b/arch/powerpc/kvm/booke.c

> > @@ -49,15 +49,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VCPU_STAT("inst_emu", emulated_inst_exits),

> >         VCPU_STAT("dec", dec_exits),

> >         VCPU_STAT("ext_intr", ext_intr_exits),

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >         VCPU_STAT("doorbell", dbell_exits),

> >         VCPU_STAT("guest doorbell", gdbell_exits),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > -       VM_STAT("remote_tlb_flush", remote_tlb_flush),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

> >         { NULL }

> >  };

> >

> > diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h

> > index 8925f3969478..57a20897f3db 100644

> > --- a/arch/s390/include/asm/kvm_host.h

> > +++ b/arch/s390/include/asm/kvm_host.h

> > @@ -361,6 +361,7 @@ struct sie_page {

> >  };

> >

> >  struct kvm_vcpu_stat {

> > +       struct kvm_vcpu_stat_common common;

> >         u64 exit_userspace;

> >         u64 exit_null;

> >         u64 exit_external_request;

> > @@ -370,13 +371,7 @@ struct kvm_vcpu_stat {

> >         u64 exit_validity;

> >         u64 exit_instruction;

> >         u64 exit_pei;

> > -       u64 halt_successful_poll;

> > -       u64 halt_attempted_poll;

> > -       u64 halt_poll_invalid;

> >         u64 halt_no_poll_steal;

> > -       u64 halt_wakeup;

> > -       u64 halt_poll_success_ns;

> > -       u64 halt_poll_fail_ns;

> >         u64 instruction_lctl;

> >         u64 instruction_lctlg;

> >         u64 instruction_stctl;

> > @@ -755,12 +750,12 @@ struct kvm_vcpu_arch {

> >  };

> >

> >  struct kvm_vm_stat {

> > +       struct kvm_vm_stat_common common;

> >         u64 inject_io;

> >         u64 inject_float_mchk;

> >         u64 inject_pfault_done;

> >         u64 inject_service_signal;

> >         u64 inject_virtio;

> > -       u64 remote_tlb_flush;

> >  };

> >

> >  struct kvm_arch_memory_slot {

> > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c

> > index 1296fc10f80c..d6bf3372bb10 100644

> > --- a/arch/s390/kvm/kvm-s390.c

> > +++ b/arch/s390/kvm/kvm-s390.c

> > @@ -72,13 +72,13 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VCPU_STAT("exit_program_interruption", exit_program_interruption),

> >         VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),

> >         VCPU_STAT("exit_operation_exception", exit_operation_exception),

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> >         VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >         VCPU_STAT("instruction_lctlg", instruction_lctlg),

> >         VCPU_STAT("instruction_lctl", instruction_lctl),

> >         VCPU_STAT("instruction_stctl", instruction_stctl),

> > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h

> > index 55efbacfc244..5bfd6893fbf6 100644

> > --- a/arch/x86/include/asm/kvm_host.h

> > +++ b/arch/x86/include/asm/kvm_host.h

> > @@ -1127,6 +1127,7 @@ struct kvm_arch {

> >  };

> >

> >  struct kvm_vm_stat {

> > +       struct kvm_vm_stat_common common;

> >         ulong mmu_shadow_zapped;

> >         ulong mmu_pte_write;

> >         ulong mmu_pde_zapped;

> > @@ -1134,13 +1135,13 @@ struct kvm_vm_stat {

> >         ulong mmu_recycled;

> >         ulong mmu_cache_miss;

> >         ulong mmu_unsync;

> > -       ulong remote_tlb_flush;

> >         ulong lpages;

> >         ulong nx_lpage_splits;

> >         ulong max_mmu_page_hash_collisions;

> >  };

> >

> >  struct kvm_vcpu_stat {

> > +       struct kvm_vcpu_stat_common common;

> >         u64 pf_fixed;

> >         u64 pf_guest;

> >         u64 tlb_flush;

> > @@ -1154,10 +1155,6 @@ struct kvm_vcpu_stat {

> >         u64 nmi_window_exits;

> >         u64 l1d_flush;

> >         u64 halt_exits;

> > -       u64 halt_successful_poll;

> > -       u64 halt_attempted_poll;

> > -       u64 halt_poll_invalid;

> > -       u64 halt_wakeup;

> >         u64 request_irq_exits;

> >         u64 irq_exits;

> >         u64 host_state_reload;

> > @@ -1168,8 +1165,6 @@ struct kvm_vcpu_stat {

> >         u64 irq_injections;

> >         u64 nmi_injections;

> >         u64 req_event;

> > -       u64 halt_poll_success_ns;

> > -       u64 halt_poll_fail_ns;

> >         u64 nested_run;

> >         u64 directed_yield_attempted;

> >         u64 directed_yield_successful;

> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c

> > index 9b6bca616929..9a93d80caff6 100644

> > --- a/arch/x86/kvm/x86.c

> > +++ b/arch/x86/kvm/x86.c

> > @@ -226,10 +226,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VCPU_STAT("irq_window", irq_window_exits),

> >         VCPU_STAT("nmi_window", nmi_window_exits),

> >         VCPU_STAT("halt_exits", halt_exits),

> > -       VCPU_STAT("halt_successful_poll", halt_successful_poll),

> > -       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),

> > -       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),

> > -       VCPU_STAT("halt_wakeup", halt_wakeup),

> > +       VCPU_STAT_COM("halt_successful_poll", halt_successful_poll),

> > +       VCPU_STAT_COM("halt_attempted_poll", halt_attempted_poll),

> > +       VCPU_STAT_COM("halt_poll_invalid", halt_poll_invalid),

> > +       VCPU_STAT_COM("halt_wakeup", halt_wakeup),

> >         VCPU_STAT("hypercalls", hypercalls),

> >         VCPU_STAT("request_irq", request_irq_exits),

> >         VCPU_STAT("irq_exits", irq_exits),

> > @@ -241,8 +241,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VCPU_STAT("nmi_injections", nmi_injections),

> >         VCPU_STAT("req_event", req_event),

> >         VCPU_STAT("l1d_flush", l1d_flush),

> > -       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),

> > -       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),

> > +       VCPU_STAT_COM("halt_poll_success_ns", halt_poll_success_ns),

> > +       VCPU_STAT_COM("halt_poll_fail_ns", halt_poll_fail_ns),

> >         VCPU_STAT("nested_run", nested_run),

> >         VCPU_STAT("directed_yield_attempted", directed_yield_attempted),

> >         VCPU_STAT("directed_yield_successful", directed_yield_successful),

> > @@ -253,7 +253,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {

> >         VM_STAT("mmu_recycled", mmu_recycled),

> >         VM_STAT("mmu_cache_miss", mmu_cache_miss),

> >         VM_STAT("mmu_unsync", mmu_unsync),

> > -       VM_STAT("remote_tlb_flush", remote_tlb_flush),

> > +       VM_STAT_COM("remote_tlb_flush", remote_tlb_flush),

> >         VM_STAT("largepages", lpages, .mode = 0444),

> >         VM_STAT("nx_largepages_splitted", nx_lpage_splits, .mode = 0444),

> >         VM_STAT("max_mmu_page_hash_collisions", max_mmu_page_hash_collisions),

> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h

> > index 2f34487e21f2..97700e41db3b 100644

> > --- a/include/linux/kvm_host.h

> > +++ b/include/linux/kvm_host.h

> > @@ -1243,10 +1243,15 @@ struct kvm_stats_debugfs_item {

> >  #define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \

> >         ((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)

> >

> > -#define VM_STAT(n, x, ...)                                                     \

> > +#define VM_STAT(n, x, ...)                                                    \

> >         { n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }

> > -#define VCPU_STAT(n, x, ...)                                                   \

> > +#define VCPU_STAT(n, x, ...)                                                  \

> >         { n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }

> > +#define VM_STAT_COM(n, x, ...)                                                \

> > +       { n, offsetof(struct kvm, stat.common.x), KVM_STAT_VM, ## __VA_ARGS__ }

> > +#define VCPU_STAT_COM(n, x, ...)                                              \

> > +       { n, offsetof(struct kvm_vcpu, stat.common.x),                         \

> > +         KVM_STAT_VCPU, ## __VA_ARGS__ }

> >

> >  extern struct kvm_stats_debugfs_item debugfs_entries[];

> >  extern struct dentry *kvm_debugfs_dir;

> > diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h

> > index a7580f69dda0..87eb05ad678b 100644

> > --- a/include/linux/kvm_types.h

> > +++ b/include/linux/kvm_types.h

> > @@ -76,5 +76,17 @@ struct kvm_mmu_memory_cache {

> >  };

> >  #endif

> >

> > +struct kvm_vm_stat_common {

> > +       ulong remote_tlb_flush;

> > +};

> > +

> > +struct kvm_vcpu_stat_common {

> > +       u64 halt_successful_poll;

> > +       u64 halt_attempted_poll;

> > +       u64 halt_poll_invalid;

> > +       u64 halt_wakeup;

> > +       u64 halt_poll_success_ns;

> > +       u64 halt_poll_fail_ns;

> > +};

> >

> >  #endif /* __KVM_TYPES_H__ */

> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c

> > index 6b4feb92dc79..34a4cf265297 100644

> > --- a/virt/kvm/kvm_main.c

> > +++ b/virt/kvm/kvm_main.c

> > @@ -330,7 +330,7 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)

> >          */

> >         if (!kvm_arch_flush_remote_tlb(kvm)

> >             || kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))

> > -               ++kvm->stat.remote_tlb_flush;

> > +               ++kvm->stat.common.remote_tlb_flush;

> >         cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);

> >  }

> >  EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs);

> > @@ -2940,9 +2940,9 @@ static inline void

> >  update_halt_poll_stats(struct kvm_vcpu *vcpu, u64 poll_ns, bool waited)

> >  {

> >         if (waited)

> > -               vcpu->stat.halt_poll_fail_ns += poll_ns;

> > +               vcpu->stat.common.halt_poll_fail_ns += poll_ns;

> >         else

> > -               vcpu->stat.halt_poll_success_ns += poll_ns;

> > +               vcpu->stat.common.halt_poll_success_ns += poll_ns;

> >  }

> >

> >  /*

> > @@ -2960,16 +2960,16 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)

> >         if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {

> >                 ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);

> >

> > -               ++vcpu->stat.halt_attempted_poll;

> > +               ++vcpu->stat.common.halt_attempted_poll;

> >                 do {

> >                         /*

> >                          * This sets KVM_REQ_UNHALT if an interrupt

> >                          * arrives.

> >                          */

> >                         if (kvm_vcpu_check_block(vcpu) < 0) {

> > -                               ++vcpu->stat.halt_successful_poll;

> > +                               ++vcpu->stat.common.halt_successful_poll;

> >                                 if (!vcpu_valid_wakeup(vcpu))

> > -                                       ++vcpu->stat.halt_poll_invalid;

> > +                                       ++vcpu->stat.common.halt_poll_invalid;

> >                                 goto out;

> >                         }

> >                         poll_end = cur = ktime_get();

> > @@ -3027,7 +3027,7 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)

> >         waitp = kvm_arch_vcpu_get_wait(vcpu);

> >         if (rcuwait_wake_up(waitp)) {

> >                 WRITE_ONCE(vcpu->ready, true);

> > -               ++vcpu->stat.halt_wakeup;

> > +               ++vcpu->stat.common.halt_wakeup;

> >                 return true;

> >         }

> >

> > --

> > 2.31.1.818.g46aad6cb9e-goog

> >

Thanks David!

Jing