[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC qom-next v5 8/8] cpus: reclaim allocated vCPU objects
From: |
Chen Fan |
Subject: |
[Qemu-devel] [RFC qom-next v5 8/8] cpus: reclaim allocated vCPU objects |
Date: |
Mon, 23 Dec 2013 17:04:09 +0800 |
After ACPI get a signal to eject a vCPU, then it will notify
the vCPU thread to exit in KVM, and the vCPU must be removed from CPU list,
before the vCPU really removed, there will release the all related vCPU objects.
Signed-off-by: Chen Fan <address@hidden>
---
cpus.c | 39 +++++++++++++++++++++++++++++++++++++++
include/qom/cpu.h | 1 +
include/sysemu/kvm.h | 1 +
kvm-all.c | 25 +++++++++++++++++++++++++
4 files changed, 66 insertions(+)
diff --git a/cpus.c b/cpus.c
index 5829d24..c16476d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -786,6 +786,26 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void
*data), void *data)
qemu_cpu_kick(cpu);
}
+static void qemu_kvm_destroy_vcpu(CPUState *cpu)
+{
+ CPU_REMOVE(cpu);
+
+ if (kvm_destroy_vcpu(cpu) < 0) {
+ fprintf(stderr, "kvm_destroy_vcpu failed.\n");
+ exit(1);
+ }
+
+ object_property_set_bool(OBJECT(cpu), false, "realized", NULL);
+ object_unparent(OBJECT(cpu));
+}
+
+static void qemu_tcg_destroy_vcpu(CPUState *cpu)
+{
+ CPU_REMOVE(cpu);
+ object_property_set_bool(OBJECT(cpu), false, "realized", NULL);
+ object_unparent(OBJECT(cpu));
+}
+
static void flush_queued_work(CPUState *cpu)
{
struct qemu_work_item *wi;
@@ -877,6 +897,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
}
}
qemu_kvm_wait_io_event(cpu);
+ if (cpu->exit && !cpu_can_run(cpu)) {
+ qemu_kvm_destroy_vcpu(cpu);
+ qemu_mutex_unlock(&qemu_global_mutex);
+ return NULL;
+ }
}
return NULL;
@@ -929,6 +954,7 @@ static void tcg_exec_all(void);
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
+ CPUState *remove_cpu = NULL;
qemu_tcg_init_cpu_signals();
qemu_thread_get_self(cpu->thread);
@@ -961,6 +987,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
}
qemu_tcg_wait_io_event();
+ CPU_FOREACH(cpu) {
+ if (cpu->exit && !cpu_can_run(cpu)) {
+ remove_cpu = cpu;
+ break;
+ }
+ }
+ if (remove_cpu) {
+ qemu_tcg_destroy_vcpu(remove_cpu);
+ remove_cpu = NULL;
+ }
}
return NULL;
@@ -1298,6 +1334,9 @@ static void tcg_exec_all(void)
break;
}
} else if (cpu->stop || cpu->stopped) {
+ if (cpu->exit) {
+ next_cpu = CPU_NEXT(cpu);
+ }
break;
}
}
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 4412fb0..f1a440e 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -208,6 +208,7 @@ struct CPUState {
QTAILQ_HEAD(CPUTailQ, CPUState);
extern struct CPUTailQ cpus;
#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
+#define CPU_REMOVE(cpu) QTAILQ_REMOVE(&cpus, cpu, node)
#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 3b25f27..f3f1279 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -167,6 +167,7 @@ int kvm_has_intx_set_mask(void);
int kvm_init_vcpu(CPUState *cpu);
int kvm_cpu_exec(CPUState *cpu);
+int kvm_destroy_vcpu(CPUState *cpu);
#ifdef NEED_CPU_H
diff --git a/kvm-all.c b/kvm-all.c
index 3937754..5a42bf1 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -227,6 +227,31 @@ static void kvm_reset_vcpu(void *opaque)
kvm_arch_reset_vcpu(cpu);
}
+int kvm_destroy_vcpu(CPUState *cpu)
+{
+ KVMState *s = kvm_state;
+ long mmap_size;
+ int ret = 0;
+
+ DPRINTF("kvm_destroy_vcpu\n");
+
+ mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
+ if (mmap_size < 0) {
+ ret = mmap_size;
+ DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
+ goto err;
+ }
+
+ ret = munmap(cpu->kvm_run, mmap_size);
+ if (ret < 0) {
+ goto err;
+ }
+
+ close(cpu->kvm_fd);
+err:
+ return ret;
+}
+
int kvm_init_vcpu(CPUState *cpu)
{
KVMState *s = kvm_state;
--
1.8.1.4
- [Qemu-devel] [RFC qom-next v5 0/8] i386: add cpu hot remove support, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 1/8] x86: move apic_state field from CPUX86State to X86CPU, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 2/8] x86: add x86_cpu_unrealizefn() for cpu apic remove, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 8/8] cpus: reclaim allocated vCPU objects,
Chen Fan <=
- [Qemu-devel] [RFC qom-next v5 3/8] qmp: add 'cpu-del' command support, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 4/8] qom cpu: rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier', Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 7/8] piix4: implement function cpu_status_write() for vcpu ejection, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 6/8] i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c, Chen Fan, 2013/12/23
- [Qemu-devel] [RFC qom-next v5 5/8] qom cpu: add UNPLUG cpu notifier support, Chen Fan, 2013/12/23