accel/kvm/kvm-accel-ops.c | 43 +++++++++++++++++++++++++++++++++++++++
hw/arm/virt.c | 25 +++++++++++++++++++++++
include/hw/arm/virt.h | 1 +
3 files changed, 69 insertions(+)
@@ -26,6 +26,47 @@
#include <linux/kvm.h>
#include "kvm-cpus.h"
+extern bool enable_kata_affinity;
+
+void BindCpu(unsigned int n);
+unsigned int get_cpuset_cpu_id(unsigned int thread_id, cpu_set_t *set);
+void bind_cpu_thread(unsigned long vcpu_id);
+
+void BindCpu(unsigned int n)
+{
+ cpu_set_t cpuSet;
+ CPU_ZERO(&cpuSet);
+ CPU_SET(n, &cpuSet);
+ pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet);
+}
+
+unsigned int get_cpuset_cpu_id(unsigned int thread_id, cpu_set_t *set)
+{
+ unsigned int i, find_num;
+
+ find_num = 0;
+ for (i = 0; i < 256; i++) {
+ if(CPU_ISSET(i, set)) {
+ find_num++;
+ if (find_num == thread_id + 1)
+ return i;
+ }
+ }
+ return i;
+}
+
+void bind_cpu_thread(unsigned long vcpu_id)
+{
+ unsigned int cpu_id;
+ pid_t pid = getpid();
+ cpu_set_t p_cpuSet;
+
+ sched_getaffinity(pid, sizeof(cpu_set_t), &p_cpuSet);
+ cpu_id = get_cpuset_cpu_id(vcpu_id, &p_cpuSet);
+ if (cpu_id < 256)
+ BindCpu(cpu_id);
+}
+
static void *kvm_vcpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@@ -39,6 +80,8 @@ static void *kvm_vcpu_thread_fn(void *arg)
cpu->neg.can_do_io = true;
current_cpu = cpu;
+ if (enable_kata_affinity)
+ bind_cpu_thread(kvm_arch_vcpu_id(cpu));
r = kvm_init_vcpu(cpu, &error_fatal);
kvm_init_cpu_signals(cpu);
@@ -233,6 +233,8 @@ static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("max"),
};
+bool enable_kata_affinity = false;
+
static CPUArchId *virt_find_cpu_slot(MachineState *ms, int vcpuid);
static int virt_get_socket_id(const MachineState *ms, int cpu_index);
static int virt_get_cluster_id(const MachineState *ms, int cpu_index);
@@ -2572,6 +2574,13 @@ static void machvirt_init(MachineState *machine)
tag_sysmem, -1);
}
}
+ if (object_property_find(OBJECT(current_machine), "kata-affinity")) {
+ g_autofree char *kata_affinity = object_property_get_str(OBJECT(current_machine),
+ "kata-affinity", &error_abort);
+ if (!strcmp(kata_affinity, "on")) {
+ enable_kata_affinity = true;
+ }
+ }
create_fdt(vms);
@@ -3893,6 +3902,19 @@ static void virt_set_kvm_type(Object *obj, const char *value, Error **errp G_GNU
vms->kvm_type = g_strdup(value);
}
+static char *virt_get_kata_affinity(Object *obj, Error **errp G_GNUC_UNUSED)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ return g_strdup(vms->kata_affinity);
+}
+
+static void virt_set_kata_affinity(Object *obj, const char *value, Error **errp G_GNUC_UNUSED)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ g_free(vms->kata_affinity);
+ vms->kata_affinity = g_strdup(value);
+}
+
static void virt_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -3956,6 +3978,9 @@ static void virt_instance_init(Object *obj)
object_property_add_str(obj, "kvm-type", virt_get_kvm_type, virt_set_kvm_type);
object_property_set_description(obj, "kvm-type", "CVM or Normal VM");
+
+ object_property_add_str(obj, "kata-affinity", virt_get_kata_affinity, virt_set_kata_affinity);
+ object_property_set_description(obj, "kata-affinity", "enable kata affinity or not");
}
static const TypeInfo virt_machine_info = {
@@ -184,6 +184,7 @@ struct VirtMachineState {
char *oem_id;
char *oem_table_id;
char *kvm_type;
+ char *kata_affinity;
NotifierList cpuhp_notifiers;
};
--
2.33.0