On Fri, Feb 13, 2015 at 4:10 PM, Zhu Guihua <zhugh.f...@cn.fujitsu.com> wrote: > From: Gu Zheng <guz.f...@cn.fujitsu.com> > > After ACPI get a signal to eject a vCPU, the vCPU must be > removed from CPU list,before the vCPU really removed, then > release the all related vCPU objects. > > In order to deal well with the kvm vcpus (which can not be removed without any > protection), we do not close KVM vcpu fd, just record and mark it as stopped > into a list, so that we can reuse it for the appending cpu hot-add request if > possible. It is also the approach that kvm guys suggested: > https://www.mail-archive.com/kvm@vger.kernel.org/msg102839.html > > Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> > Signed-off-by: Gu Zheng <guz.f...@cn.fujitsu.com> > Signed-off-by: Zhu Guihua <zhugh.f...@cn.fujitsu.com> > --- > cpus.c | 37 ++++++++++++++++++++++++++++++++++ > include/sysemu/kvm.h | 1 + > kvm-all.c | 57 > +++++++++++++++++++++++++++++++++++++++++++++++++++- > 3 files changed, 94 insertions(+), 1 deletion(-) > > diff --git a/cpus.c b/cpus.c > index d6e5a5f..a11941f 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -854,6 +854,24 @@ 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) { > + error_report("kvm_destroy_vcpu failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + object_unparent(OBJECT(cpu)); > +} > + > +static void qemu_tcg_destroy_vcpu(CPUState *cpu) > +{ > + CPU_REMOVE(cpu); > + object_unparent(OBJECT(cpu)); > +} > + > static void flush_queued_work(CPUState *cpu) > { > struct qemu_work_item *wi; > @@ -946,6 +964,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; > @@ -999,6 +1022,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); > @@ -1032,6 +1056,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; > @@ -1389,6 +1423,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/sysemu/kvm.h b/include/sysemu/kvm.h > index 30cb84d..560caef 100644 > --- a/include/sysemu/kvm.h > +++ b/include/sysemu/kvm.h > @@ -188,6 +188,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 05a79c2..46e7853 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -71,6 +71,12 @@ typedef struct KVMSlot > > typedef struct kvm_dirty_log KVMDirtyLog; > > +struct KVMParkedVcpu { > + unsigned long vcpu_id; > + int kvm_fd; > + QLIST_ENTRY(KVMParkedVcpu) node; > +}; > + > struct KVMState > { > AccelState parent_obj; > @@ -107,6 +113,7 @@ struct KVMState > QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; > bool direct_msi; > #endif > + QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; > }; > > #define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm") > @@ -247,6 +254,53 @@ static int kvm_set_user_memory_region(KVMState *s, > KVMSlot *slot) > return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); > } > > +int kvm_destroy_vcpu(CPUState *cpu)
You need to provide a stub for this in kvm-stub.c without which I see that aarch64-softmmu won't compile. Regards, Bharata.