|
[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 |