1. If we create vcpu thread with QEMU_THREAD_JOINABLE mode, we will get memory leak when vcpu thread exits, which will happen when hot-unplug vcpus. 2. We should use QLIST_FOREACH_SAFE instead of QLIST_FOREACH if we need to remove the entry in QLIST.
Signed-off-by: linzhecheng <li...@zju.edu.cn> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 071f4f5..fd95b18 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -282,9 +282,9 @@ err: static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id) { - struct KVMParkedVcpu *cpu; + struct KVMParkedVcpu *cpu, *next_cpu; - QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) { + QLIST_FOREACH_SAFE(cpu, &s->kvm_parked_vcpus, node, next_cpu) { if (cpu->vcpu_id == vcpu_id) { int kvm_fd; diff --git a/cpus.c b/cpus.c index 2cb0af9..de3a96b 100644 --- a/cpus.c +++ b/cpus.c @@ -1113,6 +1113,9 @@ static void qemu_kvm_destroy_vcpu(CPUState *cpu) error_report("kvm_destroy_vcpu failed"); exit(EXIT_FAILURE); } + g_free(cpu->thread); + g_free(cpu->halt_cond); + g_free(cpu->cpu_ases); } static void qemu_tcg_destroy_vcpu(CPUState *cpu) @@ -1205,6 +1208,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) cpu->created = false; qemu_cond_signal(&qemu_cpu_cond); qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); return NULL; } @@ -1850,7 +1854,7 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + cpu, QEMU_THREAD_DETACHED); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } -- 1.8.3.1