From patchwork Thu Apr 22 16:40:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 94172 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3MGxv1h008687 for ; Thu, 22 Apr 2010 16:59:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756004Ab0DVQ7x (ORCPT ); Thu, 22 Apr 2010 12:59:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39583 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755710Ab0DVQ7w (ORCPT ); Thu, 22 Apr 2010 12:59:52 -0400 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o3MGxbBw028390 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 22 Apr 2010 12:59:46 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o3MGeqeR007704; Thu, 22 Apr 2010 12:40:52 -0400 Received: from amt.cnet (vpn-9-191.rdu.redhat.com [10.11.9.191]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o3MGeomN000818; Thu, 22 Apr 2010 12:40:51 -0400 Received: from amt.cnet (amt.cnet [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 0B4F668A988; Thu, 22 Apr 2010 13:40:45 -0300 (BRT) Received: (from marcelo@localhost) by amt.cnet (8.14.3/8.14.3/Submit) id o3MGecDT001225; Thu, 22 Apr 2010 13:40:38 -0300 Date: Thu, 22 Apr 2010 13:40:38 -0300 From: Marcelo Tosatti To: Gleb Natapov Cc: "Yang, Sheng" , kvm , "bonenkamp@gmx.de" , Chris Wright Subject: Re: [UNTESTED] KVM: do not call kvm_set_irq from irq disabled section Message-ID: <20100422164038.GA1117@amt.cnet> References: <20100420155401.GA12982@amt.cnet> <201004211548.12824.sheng.yang@intel.com> <20100421155840.GA22052@amt.cnet> <20100421171227.GB10744@redhat.com> <20100421173734.GA27425@amt.cnet> <20100421175848.GB2455@redhat.com> <20100421182911.GA28343@amt.cnet> <20100421183839.GC2455@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20100421183839.GC2455@redhat.com> User-Agent: Mutt/1.5.20 (2009-08-17) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 22 Apr 2010 16:59:57 +0000 (UTC) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 0150aff..900ac05 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -241,8 +241,8 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian) { - struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state, - irq_ack_notifier); + struct kvm_kpit_state *ps = kian->priv; + raw_spin_lock(&ps->inject_lock); if (atomic_dec_return(&ps->pit_timer.pending) < 0) atomic_inc(&ps->pit_timer.pending); @@ -636,6 +636,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) CLOCK_MONOTONIC, HRTIMER_MODE_ABS); pit_state->irq_ack_notifier.gsi = 0; pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq; + pit_state->irq_ack_notifier.priv = &pit->pit_state; kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier); pit_state->pit_timer.reinject = true; mutex_unlock(&pit->pit_state.lock); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ce027d5..6c3fb06 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -404,6 +404,7 @@ struct kvm_irq_ack_notifier { struct hlist_node link; unsigned gsi; void (*irq_acked)(struct kvm_irq_ack_notifier *kian); + void *priv; }; #define KVM_ASSIGNED_MSIX_PENDING 0x1 diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 4d10b1e..779b749 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -121,8 +121,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) if (kian->gsi == -1) return; - dev = container_of(kian, struct kvm_assigned_dev_kernel, - ack_notifier); + dev = kian->priv; kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); @@ -563,6 +562,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, match->irq_source_id = -1; match->kvm = kvm; match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; + match->ack_notifier.priv = match; INIT_WORK(&match->interrupt_work, kvm_assigned_dev_interrupt_work_handler); diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index a0e8880..ebccea8 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -175,11 +175,14 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) return ret; } +#define MAX_ACK_NOTIFIER_PER_GSI 4 + void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) { struct kvm_irq_ack_notifier *kian; + struct kvm_irq_ack_notifier acks[MAX_ACK_NOTIFIER_PER_GSI]; struct hlist_node *n; - int gsi; + int gsi, i, acks_nr = 0; trace_kvm_ack_irq(irqchip, pin); @@ -188,9 +191,15 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) if (gsi != -1) hlist_for_each_entry_rcu(kian, n, &kvm->irq_ack_notifier_list, link) - if (kian->gsi == gsi) - kian->irq_acked(kian); + if (kian->gsi == gsi) { + if (acks_nr == MAX_ACK_NOTIFIER_PER_GSI) + break; + acks[acks_nr++] = *kian; + } rcu_read_unlock(); + + for (i = 0; i < acks_nr; i++) + acks[i].irq_acked(&acks[i]); } void kvm_register_irq_ack_notifier(struct kvm *kvm,