From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50992) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XTOfD-0005Op-VA for qemu-devel@nongnu.org; Mon, 15 Sep 2014 01:17:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XTOf9-00029h-86 for qemu-devel@nongnu.org; Mon, 15 Sep 2014 01:17:23 -0400 Received: from [59.151.112.132] (port=31038 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XTOf8-00029S-7C for qemu-devel@nongnu.org; Mon, 15 Sep 2014 01:17:19 -0400 Message-ID: <5416732B.4070109@cn.fujitsu.com> Date: Mon, 15 Sep 2014 13:03:39 +0800 From: Gu Zheng MIME-Version: 1.0 References: <1409197002-9498-1-git-send-email-guz.fnst@cn.fujitsu.com> <1409197002-9498-11-git-send-email-guz.fnst@cn.fujitsu.com> <20140912161503.042abc76@nial.usersys.redhat.com> In-Reply-To: <20140912161503.042abc76@nial.usersys.redhat.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Igor Mammedov Cc: qemu-devel@nongnu.org, tangchen@cn.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com, chen.fan.fnst@cn.fujitsu.com, anshul.makkar@profitbricks.com, afaerber@suse.de Hi Igor, On 09/12/2014 10:15 PM, Igor Mammedov wrote: > On Thu, 28 Aug 2014 11:36:42 +0800 > Gu Zheng wrote: >=20 >> After ACPI get a signal to eject a vCPU, the vCPU must be >> removed from CPU list=EF=BC=8Cbefore the vCPU really removed, then >> release the all related vCPU objects. >> But we do not close KVM vcpu fd, just record it into a list, in >> order to reuse it. > An additional question, > Have you checked if migration works after CPU unplug? Yes, migration works fine after CPU unplug. Thanks, Gu >=20 >> >> Signed-off-by: Chen Fan >> Signed-off-by: Gu Zheng >> --- >> cpus.c | 37 ++++++++++++++++++++++++++++++++ >> include/sysemu/kvm.h | 1 + >> kvm-all.c | 57 +++++++++++++++++++++++++++++++++++++++++++= ++++++- >> 3 files changed, 94 insertions(+), 1 deletions(-) >> >> diff --git a/cpus.c b/cpus.c >> index eee693b..0608b41 100644 >> --- a/cpus.c >> +++ b/cpus.c >> @@ -851,6 +851,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(v= oid *data), void *data) >> qemu_cpu_kick(cpu); >> } >> =20 >> +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_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; >> @@ -942,6 +960,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; >> + } >> } >> =20 >> return NULL; >> @@ -994,6 +1017,7 @@ static void tcg_exec_all(void); >> static void *qemu_tcg_cpu_thread_fn(void *arg) >> { >> CPUState *cpu =3D arg; >> + CPUState *remove_cpu =3D NULL; >> =20 >> qemu_tcg_init_cpu_signals(); >> qemu_thread_get_self(cpu->thread); >> @@ -1026,6 +1050,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 =3D cpu; >> + break; >> + } >> + } >> + if (remove_cpu) { >> + qemu_tcg_destroy_vcpu(remove_cpu); >> + remove_cpu =3D NULL; >> + } >> } >> =20 >> return NULL; >> @@ -1383,6 +1417,9 @@ static void tcg_exec_all(void) >> break; >> } >> } else if (cpu->stop || cpu->stopped) { >> + if (cpu->exit) { >> + next_cpu =3D CPU_NEXT(cpu); >> + } >> break; >> } >> } >> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h >> index 174ea36..88e2403 100644 >> --- a/include/sysemu/kvm.h >> +++ b/include/sysemu/kvm.h >> @@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void); >> =20 >> int kvm_init_vcpu(CPUState *cpu); >> int kvm_cpu_exec(CPUState *cpu); >> +int kvm_destroy_vcpu(CPUState *cpu); >> =20 >> #ifdef NEED_CPU_H >> =20 >> diff --git a/kvm-all.c b/kvm-all.c >> index 1402f4f..d0caeff 100644 >> --- a/kvm-all.c >> +++ b/kvm-all.c >> @@ -74,6 +74,12 @@ typedef struct KVMSlot >> =20 >> typedef struct kvm_dirty_log KVMDirtyLog; >> =20 >> +struct KVMParkedVcpu { >> + unsigned long vcpu_id; >> + int kvm_fd; >> + QLIST_ENTRY(KVMParkedVcpu) node; >> +}; >> + >> struct KVMState >> { >> KVMSlot *slots; >> @@ -108,6 +114,7 @@ struct KVMState >> QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_S= IZE]; >> bool direct_msi; >> #endif >> + QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; >> }; >> =20 >> KVMState *kvm_state; >> @@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, = KVMSlot *slot) >> return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); >> } >> =20 >> +int kvm_destroy_vcpu(CPUState *cpu) >> +{ >> + KVMState *s =3D kvm_state; >> + long mmap_size; >> + struct KVMParkedVcpu *vcpu =3D NULL; >> + int ret =3D 0; >> + >> + DPRINTF("kvm_destroy_vcpu\n"); >> + >> + mmap_size =3D kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); >> + if (mmap_size < 0) { >> + ret =3D mmap_size; >> + DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); >> + goto err; >> + } >> + >> + ret =3D munmap(cpu->kvm_run, mmap_size); >> + if (ret < 0) { >> + goto err; >> + } >> + >> + vcpu =3D g_malloc0(sizeof(*vcpu)); >> + vcpu->vcpu_id =3D kvm_arch_vcpu_id(cpu); >> + vcpu->kvm_fd =3D cpu->kvm_fd; >> + QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node); >> +err: >> + return ret; >> +} >> + >> +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id) >> +{ >> + struct KVMParkedVcpu *cpu; >> + >> + QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) { >> + if (cpu->vcpu_id =3D=3D vcpu_id) { >> + int kvm_fd; >> + >> + QLIST_REMOVE(cpu, node); >> + kvm_fd =3D cpu->kvm_fd; >> + g_free(cpu); >> + return kvm_fd; >> + } >> + } >> + >> + return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id); >> +} >> + >> int kvm_init_vcpu(CPUState *cpu) >> { >> KVMState *s =3D kvm_state; >> @@ -234,7 +288,7 @@ int kvm_init_vcpu(CPUState *cpu) >> =20 >> DPRINTF("kvm_init_vcpu\n"); >> =20 >> - ret =3D kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(c= pu)); >> + ret =3D kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu)); >> if (ret < 0) { >> DPRINTF("kvm_create_vcpu failed\n"); >> goto err; >> @@ -1404,6 +1458,7 @@ int kvm_init(MachineClass *mc) >> #ifdef KVM_CAP_SET_GUEST_DEBUG >> QTAILQ_INIT(&s->kvm_sw_breakpoints); >> #endif >> + QLIST_INIT(&s->kvm_parked_vcpus); >> s->vmfd =3D -1; >> s->fd =3D qemu_open("/dev/kvm", O_RDWR); >> if (s->fd =3D=3D -1) { >=20 > . >=20