From: Wei Wang <wei.w.wang@intel.com>
To: seanjc@google.com, pbonzini@redhat.com
Cc: dmatlack@google.com, vipinsh@google.com, ajones@ventanamicro.com,
eric.auger@redhat.com, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org, Wei Wang <wei.w.wang@intel.com>
Subject: [PATCH v1 03/18] KVM: selftests/kvm_util: helper functions for vcpus and threads
Date: Mon, 24 Oct 2022 19:34:30 +0800 [thread overview]
Message-ID: <20221024113445.1022147-4-wei.w.wang@intel.com> (raw)
In-Reply-To: <20221024113445.1022147-1-wei.w.wang@intel.com>
Add a vcpu thread field to the kvm_vcpu struct, so that each user
doesn't need to define an array of such threads on their own. The
private_data pointer is added and optionally used to hold user
specific data, and type casting to the user's data type will be
performed in the user vcpu thread's start_routine.
A couple of the helper functions are added to support vcpu related
operations:
pthread_create_with_name is provided to create general threads with
user specified name.
vcpu_thread_create is provided to create a vcpu thread with name in
"vcpu##id" format, vm_vcpu_threads_create is provided to create vcpu
threads for the vcpus that have been created for a vm. The thread
naming facilitates debugging, performance tuning, runtime pining etc.
An example is shown below reported from "top". With naming the vcpu
threads, the per-vcpu info becomes more noticeable:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4464 root 20 0 4248684 4.0g 1628 R 99.9 26.2 0:50.97 dirty_log_perf_
4467 root 20 0 4248684 4.0g 1628 R 99.9 26.2 0:50.93 vcpu0
4469 root 20 0 4248684 4.0g 1628 R 99.9 26.2 0:50.93 vcpu2
4470 root 20 0 4248684 4.0g 1628 R 99.9 26.2 0:50.94 vcpu3
4468 root 20 0 4248684 4.0g 1628 R 99.7 26.2 0:50.93 vcpu1
vm_vcpu_threads_join is provided to join all the vcpu threads.
vm_vcpu_threads_private_data_alloc is provided to allocate memory used
for user specific private data to each vcpu that have been created to
the vm.
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
---
.../testing/selftests/kvm/include/kvm_util.h | 20 ++
.../selftests/kvm/include/kvm_util_base.h | 2 +
tools/testing/selftests/kvm/lib/kvm_util.c | 172 ++++++++++++++++++
3 files changed, 194 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 5d5c8968fb06..036ed05e72e6 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -6,6 +6,7 @@
*/
#ifndef SELFTEST_KVM_UTIL_H
#define SELFTEST_KVM_UTIL_H
+#include <pthread.h>
#include "kvm_util_base.h"
#include "ucall_common.h"
@@ -14,4 +15,23 @@
for (i = 0, vcpu = vm->vcpus[0]; \
vcpu && i < KVM_MAX_VCPUS; vcpu = vm->vcpus[++i])
+void __pthread_create_with_name(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, char *name);
+
+void pthread_create_with_name(pthread_t *thread,
+ void *(*start_routine)(void *), void *arg, char *name);
+
+void __vcpu_thread_create(struct kvm_vcpu *vcpu, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), uint32_t private_data_size);
+
+void vcpu_thread_create(struct kvm_vcpu *vcpu, void *(*start_routine)(void *),
+ uint32_t private_data_size);
+
+void vm_vcpu_threads_create(struct kvm_vm *vm,
+ void *(*start_routine)(void *), uint32_t private_data_size);
+
+void vm_vcpu_threads_join(struct kvm_vm *vm);
+
+void vm_vcpu_threads_private_data_alloc(struct kvm_vm *vm, uint32_t data_size);
+
#endif /* SELFTEST_KVM_UTIL_H */
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index c90a9609b853..d0d6aaec0098 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -55,6 +55,8 @@ struct kvm_vcpu {
struct kvm_dirty_gfn *dirty_gfns;
uint32_t fetch_index;
uint32_t dirty_gfns_count;
+ pthread_t thread;
+ void *private_data;
};
struct userspace_mem_regions {
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 1f69f5ca8356..ba3e774087fb 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2006,3 +2006,175 @@ void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
break;
}
}
+
+/*
+ * Create a named thread with user's attribute
+ *
+ * Input Args:
+ * attr - the attribute of the thread to create
+ * start_routine - the routine to run in the thread context
+ * arg - the argument passed to start_routine
+ * name - the name of the thread
+ *
+ * Output Args:
+ * thread - the thread to be created
+ *
+ * Create a thread with a user specified name.
+ */
+void __pthread_create_with_name(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, char *name)
+{
+ int r;
+
+ r = pthread_create(thread, NULL, start_routine, arg);
+ TEST_ASSERT(!r, "thread(%s) creation failed, r = %d", name, r);
+ r = pthread_setname_np(*thread, name);
+ TEST_ASSERT(!r, "thread(%s) setting name failed, r = %d", name, r);
+}
+
+/*
+ * Create a named thread with the default thread attribute
+ *
+ * Input Args:
+ * start_routine - the routine to run in the thread context
+ * arg - the argument passed to start_routine
+ * name - the name of the thread
+ *
+ * Output Args:
+ * thread - the thread to be created
+ *
+ * Create a thread with a user specified name and default thread attribute.
+ */
+void pthread_create_with_name(pthread_t *thread,
+ void *(*start_routine)(void *), void *arg, char *name)
+{
+ __pthread_create_with_name(thread, NULL, start_routine, arg, name);
+}
+
+/*
+ * Create a vcpu thread with user's attribute
+ *
+ * Input Args:
+ * vcpu - the vcpu for which the thread is created
+ * attr - the attribute of the vcpu thread
+ * start_routine - the routine to run in the thread context
+ * private_data_size - the size of the user's per-vcpu private_data
+ *
+ * Output Args:
+ * None
+ *
+ * Create a vcpu thread with user provided attribute and the name in
+ * "vcpu-##id" format.
+ */
+void __vcpu_thread_create(struct kvm_vcpu *vcpu, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), uint32_t private_data_size)
+{
+ char vcpu_name[16];
+
+ if (private_data_size) {
+ vcpu->private_data = calloc(1, private_data_size);
+ TEST_ASSERT(vcpu->private_data, "%s: failed", __func__);
+ }
+
+ sprintf(vcpu_name, "vcpu-%d", vcpu->id);
+ __pthread_create_with_name(&vcpu->thread, attr,
+ start_routine, (void *)vcpu, vcpu_name);
+}
+
+/*
+ * Create a vcpu thread with the default thread attribute
+ *
+ * Input Args:
+ * vcpu - the vcpu for which the thread is created
+ * start_routine - the routine to run in the thread context
+ * private_data_size - the size of the user's per-vcpu private_data
+ *
+ * Output Args:
+ * None
+ *
+ * Create a vcpu thread with the default thread attribute and the name in
+ * "vcpu-##id" format, and allocate memory to be used as the vcpu thread's
+ * private data if private_data_size isn't 0.
+ */
+void vcpu_thread_create(struct kvm_vcpu *vcpu, void *(*start_routine)(void *),
+ uint32_t private_data_size)
+{
+ __vcpu_thread_create(vcpu, NULL, start_routine, private_data_size);
+}
+
+/*
+ * Create vcpu threads for all the vcpus that have been created for a VM
+ *
+ * Input Args:
+ * vm - the VM for which the vcpu threads are created
+ * start_routine - the routine to run in the thread context
+ * private_data_size - the size of the user's per-vcpu private_data
+ *
+ * Output Args:
+ * None
+ *
+ * Create vcpu threads for all the vcpus that have been created for the VM,
+ * and the thread name in "vcpu-##id" format. Allocate memory to each vcpu
+ * thread to be used for its private data if private_data_size isn't 0.
+ */
+void vm_vcpu_threads_create(struct kvm_vm *vm,
+ void *(*start_routine)(void *), uint32_t private_data_size)
+{
+ struct kvm_vcpu *vcpu;
+ uint32_t i;
+
+ vm_iterate_over_vcpus(vm, vcpu, i)
+ vcpu_thread_create(vcpu, start_routine, private_data_size);
+
+}
+
+/*
+ * Join the VM's vcpu threads
+ *
+ * Input Args:
+ * vm - the VM for which its vcpu threads should join
+ *
+ * Output Args:
+ * None
+ *
+ * Iterate over all the vcpus and join the threads.
+ */
+void vm_vcpu_threads_join(struct kvm_vm *vm)
+{
+ struct kvm_vcpu *vcpu;
+ void *one_failure;
+ unsigned long failures = 0;
+ int r, i;
+
+ vm_iterate_over_vcpus(vm, vcpu, i) {
+ r = pthread_join(vcpu->thread, &one_failure);
+ TEST_ASSERT(r == 0, "failed to join vcpu %d thread", i);
+ failures += (unsigned long)one_failure;
+ }
+
+ TEST_ASSERT(!failures, "%s: failed", __func__);
+}
+
+/*
+ * Allocate memory used for private data of the vm's vcpus
+ *
+ * Input Args:
+ * vm - the VM for which its vcpus will be assigned the allocated memory
+ * data_size - the size of the memory to allocate
+ *
+ * Output Args:
+ * None
+ *
+ * Allocate memory to be used for private data of each vcpu that has been
+ * created for vm.
+ */
+void vm_vcpu_threads_private_data_alloc(struct kvm_vm *vm, uint32_t data_size)
+{
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ vm_iterate_over_vcpus(vm, vcpu, i) {
+ vcpu->private_data = calloc(1, data_size);
+ TEST_ASSERT(vcpu->private_data, "%s: failed", __func__);
+ }
+}
--
2.27.0
next prev parent reply other threads:[~2022-10-24 11:38 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-24 11:34 [PATCH v1 00/18] KVM selftests code consolidation and cleanup Wei Wang
2022-10-24 11:34 ` [PATCH v1 01/18] KVM: selftests/kvm_util: use array of pointers to maintain vcpus in kvm_vm Wei Wang
2022-10-26 23:47 ` Sean Christopherson
2022-10-27 12:28 ` Wang, Wei W
2022-10-27 15:27 ` Sean Christopherson
2022-10-28 2:13 ` Wang, Wei W
2022-10-24 11:34 ` [PATCH v1 02/18] KVM: selftests/kvm_util: use vm->vcpus[] when create vm with vcpus Wei Wang
2022-10-24 11:34 ` Wei Wang [this message]
2022-10-27 0:09 ` [PATCH v1 03/18] KVM: selftests/kvm_util: helper functions for vcpus and threads Sean Christopherson
2022-10-27 14:02 ` Wang, Wei W
2022-10-27 14:54 ` Sean Christopherson
2022-10-24 11:34 ` [PATCH v1 04/18] KVM: selftests/kvm_page_table_test: vcpu related code consolidation Wei Wang
2022-10-24 11:34 ` [PATCH v1 05/18] KVM: selftests/hardware_disable_test: code consolidation and cleanup Wei Wang
2022-10-27 0:16 ` Sean Christopherson
2022-10-27 14:14 ` Wang, Wei W
2022-10-27 18:03 ` Sean Christopherson
2022-10-28 2:16 ` Wang, Wei W
2022-10-24 11:34 ` [PATCH v1 06/18] KVM: selftests/dirty_log_test: vcpu related code consolidation Wei Wang
2022-10-24 11:34 ` [PATCH v1 07/18] KVM: selftests/max_guest_memory_test: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 08/18] KVM: selftests/set_memory_region_test: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 09/18] KVM: selftests/steal_time: vcpu related code consolidation and cleanup Wei Wang
2022-10-27 0:17 ` Sean Christopherson
2022-10-24 11:34 ` [PATCH v1 10/18] KVM: selftests/tsc_scaling_sync: vcpu related code consolidation Wei Wang
2022-10-24 11:34 ` [PATCH v1 11/18] KVM: selftest/xapic_ipi_test: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 12/18] KVM: selftests/rseq_test: name the migration thread and some cleanup Wei Wang
2022-10-27 0:18 ` Sean Christopherson
2022-10-24 11:34 ` [PATCH v1 13/18] KVM: selftests/perf_test_util: vcpu related code consolidation Wei Wang
2022-10-24 11:34 ` [PATCH v1 14/18] KVM: selftest/memslot_perf_test: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 15/18] KVM: selftests/vgic_init: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 16/18] KVM: selftest/arch_timer: " Wei Wang
2022-10-24 11:34 ` [PATCH v1 17/18] KVM: selftests: remove the *vcpu[] input from __vm_create_with_vcpus Wei Wang
2022-10-24 11:34 ` [PATCH v1 18/18] KVM: selftests/kvm_create_max_vcpus: check KVM_MAX_VCPUS Wei Wang
2022-10-27 0:22 ` Sean Christopherson
2022-10-26 21:22 ` [PATCH v1 00/18] KVM selftests code consolidation and cleanup David Matlack
2022-10-27 12:18 ` Wang, Wei W
2022-10-27 15:44 ` Sean Christopherson
2022-10-27 16:24 ` David Matlack
2022-10-27 18:27 ` Sean Christopherson
2022-10-28 12:41 ` Andrew Jones
2022-10-28 15:49 ` Sean Christopherson
2022-11-07 18:11 ` David Matlack
2022-11-07 18:19 ` Sean Christopherson
2022-11-09 19:05 ` David Matlack
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=20221024113445.1022147-4-wei.w.wang@intel.com \
--to=wei.w.wang@intel.com \
--cc=ajones@ventanamicro.com \
--cc=dmatlack@google.com \
--cc=eric.auger@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=vipinsh@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox