Message ID | 1301029333-5077-1-git-send-email-Bharat.Bhushan@freescale.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 03/25/2011 07:02 AM, Bharat Bhushan wrote: > Following dump is observed on host when clearing the exit timing counters > > [root@p1021mds kvm]# echo -n 'c'> vm1200_vcpu0_timing > INFO: task echo:1276 blocked for more than 120 seconds. > "echo 0> /proc/sys/kernel/hung_task_timeout_secs" disables this message. > echo D 0ff5bf94 0 1276 1190 0x00000000 > Call Trace: > [c2157e40] [c0007908] __switch_to+0x9c/0xc4 > [c2157e50] [c040293c] schedule+0x1b4/0x3bc > [c2157e90] [c04032dc] __mutex_lock_slowpath+0x74/0xc0 > [c2157ec0] [c00369e4] kvmppc_init_timing_stats+0x20/0xb8 > [c2157ed0] [c0036b00] kvmppc_exit_timing_write+0x84/0x98 > [c2157ef0] [c00b9f90] vfs_write+0xc0/0x16c > [c2157f10] [c00ba284] sys_write+0x4c/0x90 > [c2157f40] [c000e320] ret_from_syscall+0x0/0x3c > > The vcpu->mutex is used by kvm_ioctl_* (KVM_RUN etc) and same was > used when clearing the stats (in kvmppc_init_timing_stats()). What happens > is that when the guest is idle then it held the vcpu->mutx. While the > exiting timing process waits for guest to release the vcpu->mutex and > a hang state is reached. > > Now using seprate lock for exit timing stats. > Applied, thanks.
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index bba3b9b..890897c 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -255,6 +255,7 @@ struct kvm_vcpu_arch { u32 dbsr; #ifdef CONFIG_KVM_EXIT_TIMING + struct mutex exit_timing_lock; struct kvmppc_exit_timing timing_exit; struct kvmppc_exit_timing timing_last_enter; u32 last_exit_type; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 9975846..ec3d2e7 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -284,6 +284,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; +#ifdef CONFIG_KVM_EXIT_TIMING + mutex_init(&vcpu->arch.exit_timing_lock); +#endif + return 0; } diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index a021f58..18f40fd 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c @@ -34,8 +34,8 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) { int i; - /* pause guest execution to avoid concurrent updates */ - mutex_lock(&vcpu->mutex); + /* Take a lock to avoid concurrent updates */ + mutex_lock(&vcpu->arch.exit_timing_lock); vcpu->arch.last_exit_type = 0xDEAD; for (i = 0; i < __NUMBER_OF_KVM_EXIT_TYPES; i++) { @@ -49,7 +49,7 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) vcpu->arch.timing_exit.tv64 = 0; vcpu->arch.timing_last_enter.tv64 = 0; - mutex_unlock(&vcpu->mutex); + mutex_unlock(&vcpu->arch.exit_timing_lock); } static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) @@ -65,6 +65,8 @@ static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) return; } + mutex_lock(&vcpu->arch.exit_timing_lock); + vcpu->arch.timing_count_type[type]++; /* sum */ @@ -93,6 +95,8 @@ static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) vcpu->arch.timing_min_duration[type] = duration; if (unlikely(duration > vcpu->arch.timing_max_duration[type])) vcpu->arch.timing_max_duration[type] = duration; + + mutex_unlock(&vcpu->arch.exit_timing_lock); } void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu)