From: Nicholas Piggin <npiggin@gmail.com>
To: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: linuxppc-dev@lists.ozlabs.org, Nicholas Piggin <npiggin@gmail.com>
Subject: [PATCH v3 6/6] KVM: PPC: selftests: Add interrupt performance tester
Date: Thu, 8 Jun 2023 13:24:25 +1000 [thread overview]
Message-ID: <20230608032425.59796-7-npiggin@gmail.com> (raw)
In-Reply-To: <20230608032425.59796-1-npiggin@gmail.com>
Add a little perf tester for interrupts that go to guest, host, and
userspace.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tools/testing/selftests/kvm/Makefile | 1 +
.../selftests/kvm/powerpc/interrupt_perf.c | 199 ++++++++++++++++++
2 files changed, 200 insertions(+)
create mode 100644 tools/testing/selftests/kvm/powerpc/interrupt_perf.c
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index aa3a8ca676c2..834f98971b0c 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -184,6 +184,7 @@ TEST_GEN_PROGS_riscv += kvm_page_table_test
TEST_GEN_PROGS_riscv += set_memory_region_test
TEST_GEN_PROGS_riscv += kvm_binary_stats_test
+TEST_GEN_PROGS_powerpc += powerpc/interrupt_perf
TEST_GEN_PROGS_powerpc += powerpc/null_test
TEST_GEN_PROGS_powerpc += powerpc/rtas_hcall
TEST_GEN_PROGS_powerpc += powerpc/tlbiel_test
diff --git a/tools/testing/selftests/kvm/powerpc/interrupt_perf.c b/tools/testing/selftests/kvm/powerpc/interrupt_perf.c
new file mode 100644
index 000000000000..50d078899e22
--- /dev/null
+++ b/tools/testing/selftests/kvm/powerpc/interrupt_perf.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test basic guest interrupt/exit performance.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sched.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/sysinfo.h>
+#include <signal.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "kselftest.h"
+#include "processor.h"
+#include "helpers.h"
+#include "hcall.h"
+
+static bool timeout;
+static unsigned long count;
+static struct kvm_vm *kvm_vm;
+
+static void set_timer(int sec)
+{
+ struct itimerval timer;
+
+ timeout = false;
+
+ timer.it_value.tv_sec = sec;
+ timer.it_value.tv_usec = 0;
+ timer.it_interval = timer.it_value;
+ TEST_ASSERT(setitimer(ITIMER_REAL, &timer, NULL) == 0,
+ "setitimer failed %s", strerror(errno));
+}
+
+static void sigalrm_handler(int sig)
+{
+ timeout = true;
+ sync_global_to_guest(kvm_vm, timeout);
+}
+
+static void init_timers(void)
+{
+ TEST_ASSERT(signal(SIGALRM, sigalrm_handler) != SIG_ERR,
+ "Failed to register SIGALRM handler, errno = %d (%s)",
+ errno, strerror(errno));
+}
+
+static void program_interrupt_handler(struct ex_regs *regs)
+{
+ regs->nia += 4;
+}
+
+static void program_interrupt_guest_code(void)
+{
+ unsigned long nr = 0;
+
+ while (!timeout) {
+ asm volatile("trap");
+ nr++;
+ barrier();
+ }
+ count = nr;
+
+ GUEST_DONE();
+}
+
+static void program_interrupt_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, program_interrupt_guest_code);
+ kvm_vm = vm;
+ vm_install_exception_handler(vm, 0x700, program_interrupt_handler);
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ barrier();
+ }
+
+ sync_global_from_guest(vm, count);
+
+ kvm_vm = NULL;
+ vm_install_exception_handler(vm, 0x700, NULL);
+
+ kvm_vm_free(vm);
+
+ printf("%lu guest interrupts per second\n", count);
+ count = 0;
+}
+
+static void heai_guest_code(void)
+{
+ unsigned long nr = 0;
+
+ while (!timeout) {
+ asm volatile(".long 0");
+ nr++;
+ barrier();
+ }
+ count = nr;
+
+ GUEST_DONE();
+}
+
+static void heai_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, heai_guest_code);
+ kvm_vm = vm;
+ vm_install_exception_handler(vm, 0x700, program_interrupt_handler);
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ barrier();
+ }
+
+ sync_global_from_guest(vm, count);
+
+ kvm_vm = NULL;
+ vm_install_exception_handler(vm, 0x700, NULL);
+
+ kvm_vm_free(vm);
+
+ printf("%lu guest exits per second\n", count);
+ count = 0;
+}
+
+static void hcall_guest_code(void)
+{
+ for (;;)
+ hcall0(H_RTAS);
+}
+
+static void hcall_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, hcall_guest_code);
+ kvm_vm = vm;
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ count++;
+ barrier();
+ }
+
+ kvm_vm = NULL;
+
+ kvm_vm_free(vm);
+
+ printf("%lu KVM exits per second\n", count);
+ count = 0;
+}
+
+struct testdef {
+ const char *name;
+ void (*test)(void);
+} testlist[] = {
+ { "guest interrupt test", program_interrupt_test},
+ { "guest exit test", heai_test},
+ { "KVM exit test", hcall_test},
+};
+
+int main(int argc, char *argv[])
+{
+ int idx;
+
+ ksft_print_header();
+
+ ksft_set_plan(ARRAY_SIZE(testlist));
+
+ init_timers();
+
+ for (idx = 0; idx < ARRAY_SIZE(testlist); idx++) {
+ testlist[idx].test();
+ ksft_test_result_pass("%s\n", testlist[idx].name);
+ }
+
+ ksft_finished(); /* Print results and exit() accordingly */
+}
--
2.40.1
WARNING: multiple messages have this Message-ID (diff)
From: Nicholas Piggin <npiggin@gmail.com>
To: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>, linuxppc-dev@lists.ozlabs.org
Subject: [PATCH v3 6/6] KVM: PPC: selftests: Add interrupt performance tester
Date: Thu, 8 Jun 2023 13:24:25 +1000 [thread overview]
Message-ID: <20230608032425.59796-7-npiggin@gmail.com> (raw)
In-Reply-To: <20230608032425.59796-1-npiggin@gmail.com>
Add a little perf tester for interrupts that go to guest, host, and
userspace.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tools/testing/selftests/kvm/Makefile | 1 +
.../selftests/kvm/powerpc/interrupt_perf.c | 199 ++++++++++++++++++
2 files changed, 200 insertions(+)
create mode 100644 tools/testing/selftests/kvm/powerpc/interrupt_perf.c
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index aa3a8ca676c2..834f98971b0c 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -184,6 +184,7 @@ TEST_GEN_PROGS_riscv += kvm_page_table_test
TEST_GEN_PROGS_riscv += set_memory_region_test
TEST_GEN_PROGS_riscv += kvm_binary_stats_test
+TEST_GEN_PROGS_powerpc += powerpc/interrupt_perf
TEST_GEN_PROGS_powerpc += powerpc/null_test
TEST_GEN_PROGS_powerpc += powerpc/rtas_hcall
TEST_GEN_PROGS_powerpc += powerpc/tlbiel_test
diff --git a/tools/testing/selftests/kvm/powerpc/interrupt_perf.c b/tools/testing/selftests/kvm/powerpc/interrupt_perf.c
new file mode 100644
index 000000000000..50d078899e22
--- /dev/null
+++ b/tools/testing/selftests/kvm/powerpc/interrupt_perf.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test basic guest interrupt/exit performance.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sched.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/sysinfo.h>
+#include <signal.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "kselftest.h"
+#include "processor.h"
+#include "helpers.h"
+#include "hcall.h"
+
+static bool timeout;
+static unsigned long count;
+static struct kvm_vm *kvm_vm;
+
+static void set_timer(int sec)
+{
+ struct itimerval timer;
+
+ timeout = false;
+
+ timer.it_value.tv_sec = sec;
+ timer.it_value.tv_usec = 0;
+ timer.it_interval = timer.it_value;
+ TEST_ASSERT(setitimer(ITIMER_REAL, &timer, NULL) == 0,
+ "setitimer failed %s", strerror(errno));
+}
+
+static void sigalrm_handler(int sig)
+{
+ timeout = true;
+ sync_global_to_guest(kvm_vm, timeout);
+}
+
+static void init_timers(void)
+{
+ TEST_ASSERT(signal(SIGALRM, sigalrm_handler) != SIG_ERR,
+ "Failed to register SIGALRM handler, errno = %d (%s)",
+ errno, strerror(errno));
+}
+
+static void program_interrupt_handler(struct ex_regs *regs)
+{
+ regs->nia += 4;
+}
+
+static void program_interrupt_guest_code(void)
+{
+ unsigned long nr = 0;
+
+ while (!timeout) {
+ asm volatile("trap");
+ nr++;
+ barrier();
+ }
+ count = nr;
+
+ GUEST_DONE();
+}
+
+static void program_interrupt_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, program_interrupt_guest_code);
+ kvm_vm = vm;
+ vm_install_exception_handler(vm, 0x700, program_interrupt_handler);
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ barrier();
+ }
+
+ sync_global_from_guest(vm, count);
+
+ kvm_vm = NULL;
+ vm_install_exception_handler(vm, 0x700, NULL);
+
+ kvm_vm_free(vm);
+
+ printf("%lu guest interrupts per second\n", count);
+ count = 0;
+}
+
+static void heai_guest_code(void)
+{
+ unsigned long nr = 0;
+
+ while (!timeout) {
+ asm volatile(".long 0");
+ nr++;
+ barrier();
+ }
+ count = nr;
+
+ GUEST_DONE();
+}
+
+static void heai_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, heai_guest_code);
+ kvm_vm = vm;
+ vm_install_exception_handler(vm, 0x700, program_interrupt_handler);
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ barrier();
+ }
+
+ sync_global_from_guest(vm, count);
+
+ kvm_vm = NULL;
+ vm_install_exception_handler(vm, 0x700, NULL);
+
+ kvm_vm_free(vm);
+
+ printf("%lu guest exits per second\n", count);
+ count = 0;
+}
+
+static void hcall_guest_code(void)
+{
+ for (;;)
+ hcall0(H_RTAS);
+}
+
+static void hcall_test(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ /* Create VM */
+ vm = vm_create_with_one_vcpu(&vcpu, hcall_guest_code);
+ kvm_vm = vm;
+
+ set_timer(1);
+
+ while (!timeout) {
+ vcpu_run(vcpu);
+ count++;
+ barrier();
+ }
+
+ kvm_vm = NULL;
+
+ kvm_vm_free(vm);
+
+ printf("%lu KVM exits per second\n", count);
+ count = 0;
+}
+
+struct testdef {
+ const char *name;
+ void (*test)(void);
+} testlist[] = {
+ { "guest interrupt test", program_interrupt_test},
+ { "guest exit test", heai_test},
+ { "KVM exit test", hcall_test},
+};
+
+int main(int argc, char *argv[])
+{
+ int idx;
+
+ ksft_print_header();
+
+ ksft_set_plan(ARRAY_SIZE(testlist));
+
+ init_timers();
+
+ for (idx = 0; idx < ARRAY_SIZE(testlist); idx++) {
+ testlist[idx].test();
+ ksft_test_result_pass("%s\n", testlist[idx].name);
+ }
+
+ ksft_finished(); /* Print results and exit() accordingly */
+}
--
2.40.1
next prev parent reply other threads:[~2023-06-08 3:31 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-08 3:24 [PATCH v3 0/6] KVM: selftests: add powerpc support Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-08 3:24 ` [PATCH v3 1/6] KVM: selftests: Move pgd_created check into virt_pgd_alloc Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-08 3:24 ` [PATCH v3 2/6] KVM: selftests: Add aligned guest physical page allocator Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-08 3:24 ` [PATCH v3 3/6] KVM: PPC: selftests: add support for powerpc Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-14 0:20 ` Joel Stanley
2023-08-02 22:44 ` Sean Christopherson
2023-08-02 22:44 ` Sean Christopherson
2023-06-08 3:24 ` [PATCH v3 4/6] KVM: PPC: selftests: add selftests sanity tests Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-08 3:24 ` [PATCH v3 5/6] KVM: PPC: selftests: Add a TLBIEL virtualisation tester Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin
2023-06-08 3:24 ` Nicholas Piggin [this message]
2023-06-08 3:24 ` [PATCH v3 6/6] KVM: PPC: selftests: Add interrupt performance tester Nicholas Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230608032425.59796-7-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.