From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lmc15-0002CQ-Nb for qemu-devel@nongnu.org; Wed, 25 Mar 2009 18:56:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lmc0z-000243-GI for qemu-devel@nongnu.org; Wed, 25 Mar 2009 18:56:10 -0400 Received: from [199.232.76.173] (port=51791 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lmc0z-00023n-A9 for qemu-devel@nongnu.org; Wed, 25 Mar 2009 18:56:05 -0400 Received: from mx2.redhat.com ([66.187.237.31]:51080) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Lmc0y-0006IS-OW for qemu-devel@nongnu.org; Wed, 25 Mar 2009 18:56:05 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2PMu42M032478 for ; Wed, 25 Mar 2009 18:56:04 -0400 Message-Id: <20090325225439.408403440@amt.cnet> Date: Wed, 25 Mar 2009 19:47:24 -0300 From: Marcelo Tosatti References: <20090325224714.853788328@amt.cnet> Content-Disposition: inline; filename=kvm Subject: [Qemu-devel] [patch 10/10] qemu: basic kvm iothread support Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Marcelo Tosatti Allow the iothread to run while vcpu is in guest mode. To be tuned with SMP support. Signed-off-by: Marcelo Tosatti Index: trunk/kvm-all.c =================================================================== --- trunk.orig/kvm-all.c +++ trunk/kvm-all.c @@ -451,6 +451,7 @@ int kvm_cpu_exec(CPUState *env) do { kvm_arch_pre_run(env, run); + kvm_pre_run(env); if (env->exit_request) { dprintf("interrupt exit requested\n"); @@ -459,6 +460,7 @@ int kvm_cpu_exec(CPUState *env) } ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); + kvm_post_run(env); kvm_arch_post_run(env, run); if (ret == -EINTR || ret == -EAGAIN) { Index: trunk/kvm.h =================================================================== --- trunk.orig/kvm.h +++ trunk/kvm.h @@ -27,6 +27,10 @@ extern int kvm_allowed; struct kvm_run; +/* main loop interface, vl.c */ +void kvm_pre_run(CPUState *env); +void kvm_post_run(CPUState *env); + /* external API */ int kvm_init(int smp_cpus); Index: trunk/target-i386/helper.c =================================================================== --- trunk.orig/target-i386/helper.c +++ trunk/target-i386/helper.c @@ -1668,9 +1668,6 @@ CPUX86State *cpu_x86_init(const char *cp #ifdef USE_KQEMU kqemu_init(env); #endif - if (kvm_enabled()) - kvm_init_vcpu(env); - qemu_init_vcpu(env); return env; Index: trunk/target-ppc/helper.c =================================================================== --- trunk.orig/target-ppc/helper.c +++ trunk/target-ppc/helper.c @@ -2829,8 +2829,6 @@ CPUPPCState *cpu_ppc_init (const char *c cpu_ppc_register_internal(env, def); cpu_ppc_reset(env); - if (kvm_enabled()) - kvm_init_vcpu(env); qemu_init_vcpu(env); return env; Index: trunk/vl.c =================================================================== --- trunk.orig/vl.c +++ trunk/vl.c @@ -3842,6 +3842,8 @@ void qemu_cpu_kick(void *_env) { CPUState *env = _env; qemu_cond_broadcast(env->halt_cond); + if (kvm_enabled()) + qemu_thread_signal(env->thread, SIGUSR1); } int qemu_cpu_self(void *env) @@ -3902,6 +3904,16 @@ static void qemu_signal_lock(unsigned in qemu_mutex_unlock(&qemu_fair_mutex); } +static void qemu_mutex_lock_iothread(void) +{ + if (kvm_enabled()) { + qemu_mutex_lock(&qemu_fair_mutex); + qemu_mutex_lock(&qemu_global_mutex); + qemu_mutex_unlock(&qemu_fair_mutex); + } else + qemu_signal_lock(100); +} + static int all_vcpus_paused(void) { CPUState *penv = first_cpu; @@ -3998,7 +4010,7 @@ void main_loop_wait(int timeout) */ qemu_mutex_unlock(&qemu_global_mutex); ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - qemu_signal_lock(100); + qemu_mutex_lock_iothread(); if (ret > 0) { IOHandlerRecord **pioh; @@ -4206,9 +4218,8 @@ static void *cpu_main_loop(void *arg) return NULL; } -void qemu_init_vcpu(void *_env) +static void tcg_init_vcpu(CPUState *env) { - CPUState *env = _env; /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { env->thread = qemu_mallocz(sizeof(QemuThread)); @@ -4225,6 +4236,39 @@ void qemu_init_vcpu(void *_env) } } +static void kvm_start_vcpu(CPUState *env) +{ + kvm_init_vcpu(env); + env->thread = qemu_mallocz(sizeof(QemuThread)); + env->halt_cond = qemu_mallocz(sizeof(QemuCond)); + qemu_cond_init(env->halt_cond); + qemu_thread_create(env->thread, cpu_main_loop, env); + while (env->created == 0) + qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); +} + +void kvm_pre_run(CPUState *env) +{ + cpu_single_env = NULL; + qemu_mutex_unlock(&qemu_global_mutex); +} + +void kvm_post_run(CPUState *env) +{ + qemu_mutex_lock(&qemu_global_mutex); + cpu_single_env = env; +} + +void qemu_init_vcpu(void *_env) +{ + CPUState *env = _env; + + if (kvm_enabled()) + kvm_start_vcpu(env); + else + tcg_init_vcpu(env); +} + static void qemu_init_state(void) { qemu_cond_init(&qemu_pause_cond);