[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v2] x86/cpu: initialize the CPU concurrently
From: |
Zhenyu Ye |
Subject: |
[RFC PATCH v2] x86/cpu: initialize the CPU concurrently |
Date: |
Mon, 21 Dec 2020 19:36:18 +0800 |
User-agent: |
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 |
Providing a optional mechanism to wait for all VCPU threads be
created out of qemu_init_vcpu(), then we can initialize the cpu
concurrently on the x86 architecture.
This reduces the time of creating virtual machines. For example, when
the haxm is used as the accelerator, cpus_accel->create_vcpu_thread()
will cause at least 200ms for each cpu, extremely prolong the boot
time.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: eillon <yezhenyu2@huawei.com>
---
hw/i386/x86.c | 3 +++
include/hw/core/cpu.h | 13 +++++++++++++
softmmu/cpus.c | 21 +++++++++++++++++++--
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 6329f90ef9..09afff724a 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -108,6 +108,8 @@ void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id,
Error **errp)
if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
goto out;
}
+
+ CPU(cpu)->async_init = true;
qdev_realize(DEVICE(cpu), NULL, errp);
out:
@@ -137,6 +139,7 @@ void x86_cpus_init(X86MachineState *x86ms, int
default_cpu_version)
for (i = 0; i < ms->smp.cpus; i++) {
x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal);
}
+ qemu_wait_all_vcpu_threads_init();
}
void x86_rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 8e7552910d..55c2c17d93 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -467,6 +467,12 @@ struct CPUState {
/* track IOMMUs whose translations we've cached in the TCG TLB */
GArray *iommu_notifiers;
+
+ /*
+ * If true, qemu_init_vcpu() will not wait for the VCPU thread to be
created
+ * before returning.
+ */
+ bool async_init;
};
typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
@@ -977,6 +983,13 @@ void start_exclusive(void);
*/
void end_exclusive(void);
+/**
+ * qemu_wait_all_vcpu_threads_init:
+ *
+ * Wait for all VCPU threads to be created.
+ */
+void qemu_wait_all_vcpu_threads_init(void);
+
/**
* qemu_init_vcpu:
* @cpu: The vCPU to initialize.
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index 1dc20b9dc3..d76853d356 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -601,6 +601,23 @@ void cpus_register_accel(const CpusAccel *ca)
cpus_accel = ca;
}
+static void qemu_wait_vcpu_thread_init(CPUState *cpu)
+{
+ while (!cpu->created) {
+ qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+ }
+}
+
+void qemu_wait_all_vcpu_threads_init(void)
+{
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ printf("***** cpuid: %d\n", cpu->cpu_index);
+ qemu_wait_vcpu_thread_init(cpu);
+ }
+}
+
void qemu_init_vcpu(CPUState *cpu)
{
MachineState *ms = MACHINE(qdev_get_machine());
@@ -622,8 +639,8 @@ void qemu_init_vcpu(CPUState *cpu)
g_assert(cpus_accel != NULL && cpus_accel->create_vcpu_thread != NULL);
cpus_accel->create_vcpu_thread(cpu);
- while (!cpu->created) {
- qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+ if (!cpu->async_init) {
+ qemu_wait_vcpu_thread_init(cpu);
}
}
--
2.22.0.windows.1
- [RFC PATCH v2] x86/cpu: initialize the CPU concurrently,
Zhenyu Ye <=