[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.5] Revert "dpci: move from an hvm_irq_dpci (and struct domain) to an hvm_dirq_dpci model"
commit a8ac2290ed95dbbc0dc1bdde86fc3a49fe784b28 Author: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> AuthorDate: Mon Jan 12 11:30:05 2015 -0500 Commit: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> CommitDate: Mon Jan 12 11:53:24 2015 -0500 Revert "dpci: move from an hvm_irq_dpci (and struct domain) to an hvm_dirq_dpci model" This reverts commit aeeea485bcfe2a517ed9bcb3ba1c3be0f6824e07. As there are issues with huge amount of MSI-X going off. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- xen/drivers/passthrough/io.c | 75 ++++++++++++---------------------------- xen/drivers/passthrough/pci.c | 4 +- xen/include/xen/hvm/irq.h | 2 +- 3 files changed, 26 insertions(+), 55 deletions(-) diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c index dceb17e..4cd32b5 100644 --- a/xen/drivers/passthrough/io.c +++ b/xen/drivers/passthrough/io.c @@ -27,7 +27,7 @@ #include <xen/hvm/irq.h> #include <xen/tasklet.h> -static void hvm_dirq_assist(unsigned long arg); +static void hvm_dirq_assist(unsigned long _d); bool_t pt_irq_need_timer(uint32_t flags) { @@ -114,6 +114,9 @@ int pt_irq_create_bind( spin_unlock(&d->event_lock); return -ENOMEM; } + softirq_tasklet_init( + &hvm_irq_dpci->dirq_tasklet, + hvm_dirq_assist, (unsigned long)d); for ( i = 0; i < NR_HVM_IRQS; i++ ) INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]); @@ -141,18 +144,6 @@ int pt_irq_create_bind( HVM_IRQ_DPCI_GUEST_MSI; pirq_dpci->gmsi.gvec = pt_irq_bind->u.msi.gvec; pirq_dpci->gmsi.gflags = pt_irq_bind->u.msi.gflags; - /* - * 'pt_irq_create_bind' can be called after 'pt_irq_destroy_bind'. - * The 'pirq_cleanup_check' which would free the structure is only - * called if the event channel for the PIRQ is active. However - * OS-es that use event channels usually bind PIRQs to eventds - * and unbind them before calling 'pt_irq_destroy_bind' - with the - * result that we re-use the 'dpci' structure. This can be - * reproduced with unloading and loading the driver for a device. - * - * As such on every 'pt_irq_create_bind' call we MUST set it. - */ - pirq_dpci->dom = d; /* bind after hvm_irq_dpci is setup to avoid race with irq handler*/ rc = pirq_guest_bind(d->vcpu[0], info, 0); if ( rc == 0 && pt_irq_bind->u.msi.gtable ) @@ -165,7 +156,6 @@ int pt_irq_create_bind( { pirq_dpci->gmsi.gflags = 0; pirq_dpci->gmsi.gvec = 0; - pirq_dpci->dom = NULL; pirq_dpci->flags = 0; pirq_cleanup_check(info, d); spin_unlock(&d->event_lock); @@ -242,7 +232,6 @@ int pt_irq_create_bind( { unsigned int share; - /* MUST be set, as the pirq_dpci can be re-used. */ pirq_dpci->dom = d; if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI_TRANSLATE ) { @@ -426,18 +415,11 @@ void pt_pirq_init(struct domain *d, struct hvm_pirq_dpci *dpci) { INIT_LIST_HEAD(&dpci->digl_list); dpci->gmsi.dest_vcpu_id = -1; - softirq_tasklet_init(&dpci->tasklet, hvm_dirq_assist, (unsigned long)dpci); } bool_t pt_pirq_cleanup_check(struct hvm_pirq_dpci *dpci) { - if ( !dpci->flags ) - { - tasklet_kill(&dpci->tasklet); - dpci->dom = NULL; - return 1; - } - return 0; + return !dpci->flags; } int pt_pirq_iterate(struct domain *d, @@ -477,7 +459,7 @@ int hvm_do_IRQ_dpci(struct domain *d, struct pirq *pirq) return 0; pirq_dpci->masked = 1; - tasklet_schedule(&pirq_dpci->tasklet); + tasklet_schedule(&dpci->dirq_tasklet); return 1; } @@ -531,27 +513,9 @@ void hvm_dpci_msi_eoi(struct domain *d, int vector) spin_unlock(&d->event_lock); } -static void hvm_dirq_assist(unsigned long arg) +static int _hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci, + void *arg) { - struct hvm_pirq_dpci *pirq_dpci = (struct hvm_pirq_dpci *)arg; - struct domain *d = pirq_dpci->dom; - - /* - * We can be racing with 'pt_irq_destroy_bind' - with us being scheduled - * right before 'pirq_guest_unbind' gets called - but us not yet executed. - * - * And '->dom' gets cleared later in the destroy path. We exit and clear - * 'masked' - which is OK as later in this code we would - * do nothing except clear the ->masked field anyhow. - */ - if ( !d ) - { - pirq_dpci->masked = 0; - return; - } - ASSERT(d->arch.hvm_domain.irq.dpci); - - spin_lock(&d->event_lock); if ( test_and_clear_bool(pirq_dpci->masked) ) { struct pirq *pirq = dpci_pirq(pirq_dpci); @@ -562,17 +526,13 @@ static void hvm_dirq_assist(unsigned long arg) send_guest_pirq(d, pirq); if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI ) - { - spin_unlock(&d->event_lock); - return; - } + return 0; } if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI ) { vmsi_deliver_pirq(d, pirq_dpci); - spin_unlock(&d->event_lock); - return; + return 0; } list_for_each_entry ( digl, &pirq_dpci->digl_list, list ) @@ -585,8 +545,7 @@ static void hvm_dirq_assist(unsigned long arg) { /* for translated MSI to INTx interrupt, eoi as early as possible */ __msi_pirq_eoi(pirq_dpci); - spin_unlock(&d->event_lock); - return; + return 0; } /* @@ -599,6 +558,18 @@ static void hvm_dirq_assist(unsigned long arg) ASSERT(pt_irq_need_timer(pirq_dpci->flags)); set_timer(&pirq_dpci->timer, NOW() + PT_IRQ_TIME_OUT); } + + return 0; +} + +static void hvm_dirq_assist(unsigned long _d) +{ + struct domain *d = (struct domain *)_d; + + ASSERT(d->arch.hvm_domain.irq.dpci); + + spin_lock(&d->event_lock); + pt_pirq_iterate(d, _hvm_dirq_assist, NULL); spin_unlock(&d->event_lock); } diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 81e8a3a..1eba833 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -767,8 +767,6 @@ static int pci_clean_dpci_irq(struct domain *d, xfree(digl); } - tasklet_kill(&pirq_dpci->tasklet); - return 0; } @@ -786,6 +784,8 @@ static void pci_clean_dpci_irqs(struct domain *d) hvm_irq_dpci = domain_get_irq_dpci(d); if ( hvm_irq_dpci != NULL ) { + tasklet_kill(&hvm_irq_dpci->dirq_tasklet); + pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); d->arch.hvm_domain.irq.dpci = NULL; diff --git a/xen/include/xen/hvm/irq.h b/xen/include/xen/hvm/irq.h index 94a550a..c89f4b1 100644 --- a/xen/include/xen/hvm/irq.h +++ b/xen/include/xen/hvm/irq.h @@ -88,6 +88,7 @@ struct hvm_irq_dpci { DECLARE_BITMAP(isairq_map, NR_ISAIRQS); /* Record of mapped Links */ uint8_t link_cnt[NR_LINK]; + struct tasklet dirq_tasklet; }; /* Machine IRQ to guest device/intx mapping. */ @@ -99,7 +100,6 @@ struct hvm_pirq_dpci { struct domain *dom; struct hvm_gmsi_info gmsi; struct timer timer; - struct tasklet tasklet; }; void pt_pirq_init(struct domain *, struct hvm_pirq_dpci *); -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.5 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |