aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorBharat Bhushan <r65777@freescale.com>2011-03-25 01:02:13 -0400
committerAvi Kivity <avi@redhat.com>2011-05-11 07:57:04 -0400
commit09000adb86550d2895b64faa52e64eaec3cae7b2 (patch)
treee2a932b4735b1296e2df760fea26030286f9daaa /arch/powerpc/kvm
parent7c5625227ff8c81953e953d8e25c3eba2ab0aeb3 (diff)
KVM: PPC: Fix issue clearing exit timing counters
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. Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com> Acked-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/powerpc.c4
-rw-r--r--arch/powerpc/kvm/timing.c10
2 files changed, 11 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 99758460efde..ec3d2e75c0a8 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)
284 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); 284 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
285 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; 285 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
286 286
287#ifdef CONFIG_KVM_EXIT_TIMING
288 mutex_init(&vcpu->arch.exit_timing_lock);
289#endif
290
287 return 0; 291 return 0;
288} 292}
289 293
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c
index a021f5827a33..18f40fd3e98f 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)
34{ 34{
35 int i; 35 int i;
36 36
37 /* pause guest execution to avoid concurrent updates */ 37 /* Take a lock to avoid concurrent updates */
38 mutex_lock(&vcpu->mutex); 38 mutex_lock(&vcpu->arch.exit_timing_lock);
39 39
40 vcpu->arch.last_exit_type = 0xDEAD; 40 vcpu->arch.last_exit_type = 0xDEAD;
41 for (i = 0; i < __NUMBER_OF_KVM_EXIT_TYPES; i++) { 41 for (i = 0; i < __NUMBER_OF_KVM_EXIT_TYPES; i++) {
@@ -49,7 +49,7 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu)
49 vcpu->arch.timing_exit.tv64 = 0; 49 vcpu->arch.timing_exit.tv64 = 0;
50 vcpu->arch.timing_last_enter.tv64 = 0; 50 vcpu->arch.timing_last_enter.tv64 = 0;
51 51
52 mutex_unlock(&vcpu->mutex); 52 mutex_unlock(&vcpu->arch.exit_timing_lock);
53} 53}
54 54
55static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) 55static 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)
65 return; 65 return;
66 } 66 }
67 67
68 mutex_lock(&vcpu->arch.exit_timing_lock);
69
68 vcpu->arch.timing_count_type[type]++; 70 vcpu->arch.timing_count_type[type]++;
69 71
70 /* sum */ 72 /* sum */
@@ -93,6 +95,8 @@ static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type)
93 vcpu->arch.timing_min_duration[type] = duration; 95 vcpu->arch.timing_min_duration[type] = duration;
94 if (unlikely(duration > vcpu->arch.timing_max_duration[type])) 96 if (unlikely(duration > vcpu->arch.timing_max_duration[type]))
95 vcpu->arch.timing_max_duration[type] = duration; 97 vcpu->arch.timing_max_duration[type] = duration;
98
99 mutex_unlock(&vcpu->arch.exit_timing_lock);
96} 100}
97 101
98void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu) 102void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu)