[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 4/5] QEMU Release vcpu and finally exit vcpu thr
From: |
ShaoHe Feng |
Subject: |
Re: [Qemu-devel] [PATCH 4/5] QEMU Release vcpu and finally exit vcpu thread safely |
Date: |
Tue, 29 Nov 2011 13:37:09 +0800 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 |
Ping Fan,
IMO, QEMU should Release vcpu and finally exit vcpu thread safely in
tcg mode?
---
cpus.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/cpus.c b/cpus.c
index 82530c4..cc52327 100644
--- a/cpus.c
+++ b/cpus.c
@@ -753,7 +753,7 @@ static void tcg_exec_all(void);
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *env = arg;
-
+ CPUState *prev = NULL;
qemu_tcg_init_cpu_signals();
qemu_thread_get_self(env->thread);
@@ -775,10 +775,29 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
if (use_icount && qemu_clock_deadline(vm_clock) <= 0) {
qemu_notify_event();
}
+ /*1,try to zap; 2, can safe to destroy*/
+ if (env->state == CPU_STATE_ZAPPED) {
+ goto zapout;
+ }
qemu_tcg_wait_io_event();
}
return NULL;
+zapout:
+ prev = first_cpu;
+ if (prev == env) {
+ first_cpu = env->next_cpu;
+ } else {
+ while (prev != NULL) {
+ if (prev->next_cpu == env) {
+ break;
+ }
+ prev = prev->next_cpu;
+ }
+ prev->next_cpu = env->next_cpu;
+ }
+ cpu_free(env);
+ return NULL;
}
static void qemu_cpu_kick_thread(CPUState *env)
--
1.7.5.4
, Liu Ping Fan wrote:
> From: Liu Ping Fan <address@hidden>
>
> When guest driver tell us that the vcpu is no longer needed,
> qemu can release the vcpu and finally exit vcpu thread
>
> Signed-off-by: Liu Ping Fan <address@hidden>
> ---
> cpu-defs.h | 5 +++++
> cpus.c | 21 +++++++++++++++++++++
> hmp-commands.hx | 2 +-
> hw/acpi_piix4.c | 19 ++++++++++++++++---
> hw/pci_cpustate.c | 22 ++++++++++++++++++++++
> kvm-all.c | 11 ++++++++++-
> monitor.c | 12 +++++++-----
> 7 files changed, 82 insertions(+), 10 deletions(-)
>
> diff --git a/cpu-defs.h b/cpu-defs.h
> index db48a7a..cb69a07 100644
> --- a/cpu-defs.h
> +++ b/cpu-defs.h
> @@ -153,6 +153,10 @@ typedef struct CPUWatchpoint {
> QTAILQ_ENTRY(CPUWatchpoint) entry;
> } CPUWatchpoint;
>
> +#define CPU_STATE_RUNNING 0
> +#define CPU_STATE_ZAPREQ 1
> +#define CPU_STATE_ZAPPED 2
> +
> #define CPU_TEMP_BUF_NLONGS 128
> #define CPU_COMMON \
> struct TranslationBlock *current_tb; /* currently executing TB */ \
> @@ -210,6 +214,7 @@ typedef struct CPUWatchpoint {
> uint32_t created; \
> uint32_t stop; /* Stop request */ \
> uint32_t stopped; /* Artificially stopped */ \
> + uint32_t state; /*state indicator*/ \
> struct QemuThread *thread; \
> struct QemuCond *halt_cond; \
> int thread_kicked; \
> diff --git a/cpus.c b/cpus.c
> index c996ac5..e479476 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -33,6 +33,7 @@
>
> #include "qemu-thread.h"
> #include "cpus.h"
> +#include "cpu.h"
>
> #ifndef _WIN32
> #include "compatfd.h"
> @@ -778,6 +779,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
> static void *qemu_kvm_cpu_thread_fn(void *arg)
> {
> CPUState *env = arg;
> + CPUState *prev = NULL;
> int r;
>
> qemu_mutex_lock(&qemu_global_mutex);
> @@ -808,10 +810,29 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
> cpu_handle_guest_debug(env);
> }
> }
> + /*1,try to zap; 2, can safe to destroy*/
> + if (env->state == CPU_STATE_ZAPPED) {
> + goto zapout;
> + }
> qemu_kvm_wait_io_event(env);
> }
>
> return NULL;
> +zapout:
> + prev = first_cpu;
> + if (prev == env) {
> + first_cpu = env->next_cpu;
> + } else {
> + while (prev != NULL) {
> + if (prev->next_cpu == env) {
> + break;
> + }
> + prev = prev->next_cpu;
> + }
> + prev->next_cpu = env->next_cpu;
> + }
> + cpu_free(env);
> + return NULL;
> }
>
> static void *qemu_tcg_cpu_thread_fn(void *arg)
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index ed5c9b9..b642a34 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1218,7 +1218,7 @@ ETEXI
> {
> .name = "cpu_set",
> .args_type = "cpu:i,state:s",
> - .params = "cpu [online|offline]",
> + .params = "cpu [online|offline|zap]",
> .help = "change cpu state",
> .mhandler.cmd = do_cpu_set_nr,
> },
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index f585226..1f3ed06 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -605,10 +605,23 @@ void qemu_system_cpu_hot_add(int cpu, int state)
> env->cpuid_apic_id = cpu;
> }
>
> - if (state)
> - enable_processor(s, cpu);
> - else
> + switch (state) {
> + /*zap vcpu*/
> + case 0:
> + env = qemu_get_cpu(cpu);
> + /*1 means try to zap*/
> + env->state = CPU_STATE_ZAPREQ;
> + disable_processor(s, cpu);
> + break;
> + /*offline vcpu*/
> + case 1:
> disable_processor(s, cpu);
> + break;
> + /*onine vcpu*/
> + case 2:
> + enable_processor(s, cpu);
> + break;
> + }
>
> pm_update_sci(s);
> }
> diff --git a/hw/pci_cpustate.c b/hw/pci_cpustate.c
> index fd31a1f..18402cf 100644
> --- a/hw/pci_cpustate.c
> +++ b/hw/pci_cpustate.c
> @@ -24,6 +24,8 @@
> #include "loader.h"
> #include "sysemu.h"
> #include "iov.h"
> +#include <linux/kvm.h>
> +#include "kvm.h"
>
> #define PCI_DEVICE_ID_CPUSTATE 0x1010
> #define CPUSTATE_REGS_SIZE 0x1000
> @@ -52,6 +54,26 @@ static void
> cpustate_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val,
> unsigned size)
> {
> + CPUState *env;
> + int ret;
> + struct kvm_vcpu_state state;
> + switch (addr) {
> + /*apic id*/
> + case 0:
> + env = cpu_phyid_to_cpu(val);
> + if (env != NULL) {
> + if (env->state == CPU_STATE_ZAPREQ) {
> + state.vcpu_id = env->cpu_index;
> + state.state = 1;
> + ret = kvm_vm_ioctl(env->kvm_state, KVM_SETSTATE_VCPU,
> &state);
> + }
> + }
> + break;
> + case 4:
> + break;
> + default:
> + break;
> + }
> }
>
> static uint64_t
> diff --git a/kvm-all.c b/kvm-all.c
> index 8dd354e..b295262 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -64,6 +64,7 @@ struct KVMState
> int vmfd;
> int coalesced_mmio;
> struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
> + long mmap_size;
> int broken_set_mem_region;
> int migration_log;
> int vcpu_events;
> @@ -228,7 +229,7 @@ int kvm_init_vcpu(CPUState *env)
> DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
> goto err;
> }
> -
> + env->kvm_state->mmap_size = mmap_size;
> env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED,
> env->kvm_fd, 0);
> if (env->kvm_run == MAP_FAILED) {
> @@ -1026,6 +1027,13 @@ int kvm_cpu_exec(CPUState *env)
> case KVM_EXIT_INTERNAL_ERROR:
> ret = kvm_handle_internal_error(env, run);
> break;
> + case KVM_EXIT_VCPU_DEAD:
> + ret = munmap(env->kvm_run, env->kvm_state->mmap_size);
> + ret = close(env->kvm_fd);
> + env->state = CPU_STATE_ZAPPED;
> + qemu_mutex_unlock_iothread();
> + goto out;
> + break;
> default:
> DPRINTF("kvm_arch_handle_exit\n");
> ret = kvm_arch_handle_exit(env, run);
> @@ -1033,6 +1041,7 @@ int kvm_cpu_exec(CPUState *env)
> }
> } while (ret == 0);
>
> +out:
> if (ret < 0) {
> cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
> vm_stop(VMSTOP_PANIC);
> diff --git a/monitor.c b/monitor.c
> index cb485bf..51c8c52 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -971,11 +971,13 @@ static void do_cpu_set_nr(Monitor *mon, const QDict
> *qdict)
> status = qdict_get_str(qdict, "state");
> value = qdict_get_int(qdict, "cpu");
>
> - if (!strcmp(status, "online"))
> - state = 1;
> - else if (!strcmp(status, "offline"))
> - state = 0;
> - else {
> + if (!strcmp(status, "online")) {
> + state = 2;
> + } else if (!strcmp(status, "offline")) {
> + state = 1;
> + } else if (!strcmp(status, "zap")) {
> + state = 0;
> + } else {
> monitor_printf(mon, "invalid status: %s\n", status);
> return;
> }
- [Qemu-devel] [PATCH 2/2] kvm: exit to userspace with reason KVM_EXIT_VCPU_DEAD, (continued)
[Qemu-devel] [PATCH 1/5] QEMU Add cpu_phyid_to_cpu() to map cpu phyid to CPUState, Liu Ping Fan, 2011/11/26
[Qemu-devel] [PATCH 2/5] QEMU Add cpu_free() to support arch related CPUState release, Liu Ping Fan, 2011/11/26
[Qemu-devel] [PATCH 3/5] QEMU Introduce a pci device "cpustate" to get CPU_DEAD event in guest, Liu Ping Fan, 2011/11/26
[Qemu-devel] [PATCH 4/5] QEMU Release vcpu and finally exit vcpu thread safely, Liu Ping Fan, 2011/11/26
- Re: [Qemu-devel] [PATCH 4/5] QEMU Release vcpu and finally exit vcpu thread safely,
ShaoHe Feng <=
[Qemu-devel] [PATCH 5/5] QEMU tmp patches for linux-header files, Liu Ping Fan, 2011/11/26
[Qemu-devel] [PATCH] virtio: add a pci driver to notify host the CPU_DEAD event, Liu Ping Fan, 2011/11/26