qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/3] add some vcpu-pin related functions.


From: Benyu Xu
Subject: [Qemu-devel] [PATCH 1/3] add some vcpu-pin related functions.
Date: Sat, 1 Jul 2017 22:57:08 +0800

Signed-off-by: Benyu Xu <address@hidden>
---
 cpus.c                | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/qom/cpu.h     |   9 ++++
 include/sysemu/cpus.h |   2 +
 3 files changed, 137 insertions(+)

diff --git a/cpus.c b/cpus.c
index 14bb8d5..40c3abf 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1648,6 +1648,132 @@ void cpu_remove(CPUState *cpu)
     qemu_cpu_kick(cpu);
 }
 
+int get_pcpu_num(bool pin_auto, int *pcpu_id_array)
+{
+    int pcpu_num = 0;
+#ifdef _GNU_SOURCE
+    int pcpu_range = 1024;
+    int pcpu_id = 0;
+    int ret;
+    cpu_set_t *pcpu_set;
+    size_t setsize;
+
+    pcpu_set = CPU_ALLOC(pcpu_range);
+    if (pcpu_set == NULL) {
+        pcpu_num = -1;
+        return pcpu_num;
+    }
+
+    setsize = CPU_ALLOC_SIZE(pcpu_range);
+
+    for ( ; ; ) {
+        CPU_ZERO_S(setsize, pcpu_set);
+        ret = sched_getaffinity(0, setsize, pcpu_set);
+        if (ret < 0 && errno == EINVAL && pcpu_range < 131072) {
+            CPU_FREE(pcpu_set);
+            pcpu_range *= 2;
+            pcpu_set = CPU_ALLOC(pcpu_range);
+            if (pcpu_set == NULL) {
+                pcpu_num = -1;
+                return pcpu_num;
+            }
+            setsize = CPU_ALLOC_SIZE(pcpu_range);
+            continue;
+        }
+
+        if (ret == 0) {
+            for ( ; pcpu_id < 131072; pcpu_id++) {
+                if (CPU_ISSET_S(pcpu_id, setsize, pcpu_set)) {
+                    pcpu_num++;
+                    if (pin_auto == true) {
+                        pcpu_id_array[0] = pcpu_num;
+                        pcpu_id_array[pcpu_num] = pcpu_id;
+                    }
+                }
+            }
+            CPU_FREE(pcpu_set);
+            return pcpu_num;
+        }
+        CPU_FREE(pcpu_set);
+    }
+#else
+    pcpu_num = -2;
+    return pcpu_num;
+#endif
+}
+
+void cpu_pin(CPUState *cpu, int pcpu_id)
+{
+    cpu_set_t *pcpu_id_mask;
+    size_t masksize;
+    pid_t vcpu_pid;
+    int num_cpus;
+
+    if (pcpu_id == 0) {
+        num_cpus = pcpu_id + 1;
+    } else {
+        num_cpus = pcpu_id;
+    }
+
+    pcpu_id_mask = CPU_ALLOC(num_cpus);
+    if (pcpu_id_mask == NULL) {
+        error_report("warning: can not alloc cpu set! pcpu #%d",
+                      pcpu_id);
+        return ;
+    }
+    masksize = CPU_ALLOC_SIZE(num_cpus);
+    CPU_ZERO_S(masksize, pcpu_id_mask);
+    CPU_SET_S(pcpu_id, masksize, pcpu_id_mask);
+
+    vcpu_pid = cpu->thread_id;
+
+    if (sched_setaffinity(vcpu_pid, masksize, pcpu_id_mask) != 0) {
+        error_report("warning: set affinity failed! vcpu pid=%d, pcpu #%d",
+                      vcpu_pid, pcpu_id);
+        CPU_FREE(pcpu_id_mask);
+        return ;
+    }
+
+    if (sched_getaffinity(vcpu_pid, masksize, pcpu_id_mask) != 0) {
+        error_report("warning: get affinity failed! vcpu pid=%d, pcpu #%d",
+                      vcpu_pid, pcpu_id);
+        CPU_FREE(pcpu_id_mask);
+        return ;
+        }
+
+    CPU_FREE(pcpu_id_mask);
+}
+
+/* *
+ * pcpu_id_array: content the host processor's id array to pin
+ * pcpu_id_array[0]: the processor count
+ * pcpu_id_array[1...]: the processor id to pin
+ * */
+void pin_all_vcpus(int smp_cpus_num, const int *pcpu_id_array, Error **errp)
+{
+    int pcpu_id = 0;
+    int pcpu_num = pcpu_id_array[0];
+    int vcpu_id = 0;
+    CPUState *cpu;
+
+    if (pcpu_num <= 0) {
+        return;
+    }
+
+    if (smp_cpus_num > pcpu_num) {
+        error_setg(errp,
+                "pcpu id list only has %d pcpu(s), less than smp_cpus_num %d",
+                 pcpu_num, smp_cpus_num);
+        return;
+    }
+
+    CPU_FOREACH(cpu) {
+        pcpu_id = pcpu_id_array[vcpu_id + 1];
+        cpu_pin(cpu, pcpu_id);
+        vcpu_id++;
+    }
+}
+
 void cpu_remove_sync(CPUState *cpu)
 {
     cpu_remove(cpu);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 89ddb68..8f14295 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -869,6 +869,15 @@ void cpu_exit(CPUState *cpu);
 void cpu_resume(CPUState *cpu);
 
 /**
+ * cpu_pin:
+ * @cpu: The vitual CPU to pin.
+ * @pcpu_id: The host's physical or logical processor's id.
+ *
+ * pin CPU, i.e. set the CPU's affinity.
+ */
+void cpu_pin(CPUState *cpu, int pcpu_id);
+
+/**
  * cpu_remove:
  * @cpu: The CPU to remove.
  *
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 731756d..513a0c6 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -7,6 +7,8 @@
 bool qemu_in_vcpu_thread(void);
 void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
+int  get_pcpu_num(bool pin_default, int *pcpu_id_array);
+void pin_all_vcpus(int smp_cpu_num, const int *pcpu_id_array, Error **errp);
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
 void cpu_ticks_init(void);
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]