From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: KVM: x86: fix deadlock in clock-in-progress request handling Date: Mon, 18 Mar 2013 19:20:11 +0200 Message-ID: <20130318172011.GM4020@redhat.com> References: <20130318165432.GA12342@amt.cnet> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm , Yongjie Ren To: Marcelo Tosatti Return-path: Received: from mx1.redhat.com ([209.132.183.28]:24356 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752844Ab3CRRUP (ORCPT ); Mon, 18 Mar 2013 13:20:15 -0400 Content-Disposition: inline In-Reply-To: <20130318165432.GA12342@amt.cnet> Sender: kvm-owner@vger.kernel.org List-ID: On Mon, Mar 18, 2013 at 01:54:32PM -0300, Marcelo Tosatti wrote: > > There is a deadlock in pvclock handling: > > cpu0: cpu1: > kvm_gen_update_masterclock() > kvm_guest_time_update() > spin_lock(pvclock_gtod_sync_lock) > local_irq_save(flags) > > spin_lock(pvclock_gtod_sync_lock) > > kvm_make_mclock_inprogress_request(kvm) > make_all_cpus_request() > smp_call_function_many() > > Now if smp_call_function_many() called by cpu0 tries to call function on > cpu1 there will be a deadlock. > > Fix by moving pvclock_gtod_sync_lock protected section outside irq > disabled section. > > Analyzed by Gleb Natapov > Reported-and-Tested-by: Yongjie Ren > Signed-off-by: Marcelo Tosatti > Acked-by: Gleb Natapov > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index f71500a..f7c850b 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -1416,15 +1416,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) > kernel_ns = 0; > host_tsc = 0; > > - /* Keep irq disabled to prevent changes to the clock */ > - local_irq_save(flags); > - this_tsc_khz = __get_cpu_var(cpu_tsc_khz); > - if (unlikely(this_tsc_khz == 0)) { > - local_irq_restore(flags); > - kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); > - return 1; > - } > - > /* > * If the host uses TSC clock, then passthrough TSC as stable > * to the guest. > @@ -1436,6 +1427,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) > kernel_ns = ka->master_kernel_ns; > } > spin_unlock(&ka->pvclock_gtod_sync_lock); > + > + /* Keep irq disabled to prevent changes to the clock */ > + local_irq_save(flags); > + this_tsc_khz = __get_cpu_var(cpu_tsc_khz); > + if (unlikely(this_tsc_khz == 0)) { > + local_irq_restore(flags); > + kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); > + return 1; > + } > if (!use_master_clock) { > host_tsc = native_read_tsc(); > kernel_ns = get_kernel_ns(); -- Gleb.