aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kvm/kvm-ia64.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-05-07 16:55:12 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:53 -0400
commit32f8840064d88cc3f6e85203aec7b6b57bebcb97 (patch)
tree29a42942c71e9bdf1f3e71aa1674a29aa13ce320 /arch/ia64/kvm/kvm-ia64.c
parentd149c731e4f71982247a14409951259f36271dd7 (diff)
KVM: use smp_send_reschedule in kvm_vcpu_kick
KVM uses a function call IPI to cause the exit of a guest running on a physical cpu. For virtual interrupt notification there is no need to wait on IPI receival, or to execute any function. This is exactly what the reschedule IPI does, without the overhead of function IPI. So use it instead of smp_call_function_single in kvm_vcpu_kick. Also change the "guest_mode" variable to a bit in vcpu->requests, and use that to collapse multiple IPI's that would be issued between the first one and zeroing of guest mode. This allows kvm_vcpu_kick to called with interrupts disabled. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c22
1 files changed, 8 insertions, 14 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index be4413e1f43..80c57b0a21c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -668,7 +668,7 @@ again:
668 host_ctx = kvm_get_host_context(vcpu); 668 host_ctx = kvm_get_host_context(vcpu);
669 guest_ctx = kvm_get_guest_context(vcpu); 669 guest_ctx = kvm_get_guest_context(vcpu);
670 670
671 vcpu->guest_mode = 1; 671 clear_bit(KVM_REQ_KICK, &vcpu->requests);
672 672
673 r = kvm_vcpu_pre_transition(vcpu); 673 r = kvm_vcpu_pre_transition(vcpu);
674 if (r < 0) 674 if (r < 0)
@@ -685,7 +685,7 @@ again:
685 kvm_vcpu_post_transition(vcpu); 685 kvm_vcpu_post_transition(vcpu);
686 686
687 vcpu->arch.launched = 1; 687 vcpu->arch.launched = 1;
688 vcpu->guest_mode = 0; 688 set_bit(KVM_REQ_KICK, &vcpu->requests);
689 local_irq_enable(); 689 local_irq_enable();
690 690
691 /* 691 /*
@@ -1879,24 +1879,18 @@ void kvm_arch_hardware_unsetup(void)
1879{ 1879{
1880} 1880}
1881 1881
1882static void vcpu_kick_intr(void *info)
1883{
1884#ifdef DEBUG
1885 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
1886 printk(KERN_DEBUG"vcpu_kick_intr %p \n", vcpu);
1887#endif
1888}
1889
1890void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 1882void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
1891{ 1883{
1892 int ipi_pcpu = vcpu->cpu; 1884 int me;
1893 int cpu = get_cpu(); 1885 int cpu = vcpu->cpu;
1894 1886
1895 if (waitqueue_active(&vcpu->wq)) 1887 if (waitqueue_active(&vcpu->wq))
1896 wake_up_interruptible(&vcpu->wq); 1888 wake_up_interruptible(&vcpu->wq);
1897 1889
1898 if (vcpu->guest_mode && cpu != ipi_pcpu) 1890 me = get_cpu();
1899 smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0); 1891 if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
1892 if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
1893 smp_send_reschedule(cpu);
1900 put_cpu(); 1894 put_cpu();
1901} 1895}
1902 1896