From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: julien.grall@citrix.com, Ian.Campbell@citrix.com,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PATCH v9 05/10] xen/arm: physical irq follow virtual irq
Date: Thu, 24 Jul 2014 18:33:07 +0100 [thread overview]
Message-ID: <1406223192-26267-5-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1407241825570.2293@kaball.uk.xensource.com>
Migrate physical irqs to the same physical cpu that is running the vcpu
expected to receive the irqs. That is done when enabling irqs, when the
guest writes to GICD_ITARGETSR and when Xen migrates a vcpu to a
different pcpu.
In case of virq migration, if the virq is inflight and in a GICH_LR
register already, delay migrating the corresponding physical irq until
the virq is EOIed by the guest and the MIGRATING flag has been cleared.
This way we make sure that the pcpu running the old vcpu gets
interrupted with a new irq of the same kind, clearing the GICH_LR sooner.
Introduce a new arch specific function, arch_move_irqs, that is empty on
x86 and implements the vgic irq migration code on ARM.
arch_move_irqs is going to be called by from sched.c.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in v9:
- move arch_move_irqs declaration to irq.h.
Changes in v7:
- remove checks at the top of gic_irq_set_affinity, add assert instead;
- move irq_set_affinity to irq.c;
- delay setting the affinity of the physical irq when the virq is
MIGRATING until the virq is EOIed by the guest;
- do not set the affinity of MIGRATING irqs from arch_move_irqs.
Changes in v6:
- use vgic_get_target_vcpu instead of _vgic_get_target_vcpu in
arch_move_irqs.
Changes in v5:
- prettify vgic_move_irqs;
- rename vgic_move_irqs to arch_move_irqs;
- introduce helper function irq_set_affinity.
---
xen/arch/arm/gic-v2.c | 15 +++++++++++++--
xen/arch/arm/gic.c | 6 +++++-
xen/arch/arm/irq.c | 6 ++++++
xen/arch/arm/vgic.c | 21 +++++++++++++++++++++
xen/include/asm-arm/irq.h | 3 +++
xen/include/asm-x86/irq.h | 2 ++
6 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 1305542..da60a41 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -569,9 +569,20 @@ static void gicv2_guest_irq_end(struct irq_desc *desc)
/* Deactivation happens in maintenance interrupt / via GICV */
}
-static void gicv2_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
+static void gicv2_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
{
- BUG();
+ unsigned int mask;
+
+ ASSERT(!cpumask_empty(cpu_mask));
+
+ spin_lock(&gicv2.lock);
+
+ mask = gicv2_cpu_mask(cpu_mask);
+
+ /* Set target CPU mask (RAZ/WI on uniprocessor) */
+ writeb_gicd(mask, GICD_ITARGETSR + desc->irq);
+
+ spin_unlock(&gicv2.lock);
}
/* XXX different for level vs edge */
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index f5c7c91..2aa9500 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -382,7 +382,11 @@ static void gic_update_one_lr(struct vcpu *v, int i)
gic_raise_guest_irq(v, irq, p->priority);
else {
list_del_init(&p->inflight);
- clear_bit(GIC_IRQ_GUEST_MIGRATING, &p->status);
+ if ( test_and_clear_bit(GIC_IRQ_GUEST_MIGRATING, &p->status) )
+ {
+ struct vcpu *v_target = vgic_get_target_vcpu(v, irq);
+ irq_set_affinity(p->desc, cpumask_of(v_target->processor));
+ }
}
}
}
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 49ca467..7150c7a 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -134,6 +134,12 @@ static inline struct domain *irq_get_domain(struct irq_desc *desc)
return desc->action->dev_id;
}
+void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
+{
+ if ( desc != NULL )
+ desc->handler->set_affinity(desc, cpu_mask);
+}
+
int request_irq(unsigned int irq, unsigned int irqflags,
void (*handler)(int, void *, struct cpu_user_regs *),
const char *devname, void *dev_id)
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 02e5985..299ae7e 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -182,6 +182,7 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq)
if ( list_empty(&p->inflight) )
{
+ irq_set_affinity(p->desc, cpumask_of(new->processor));
spin_unlock_irqrestore(&old->arch.vgic.lock, flags);
return;
}
@@ -190,6 +191,7 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq)
{
list_del_init(&p->lr_queue);
list_del_init(&p->inflight);
+ irq_set_affinity(p->desc, cpumask_of(new->processor));
spin_unlock_irqrestore(&old->arch.vgic.lock, flags);
vgic_vcpu_inject_irq(new, irq);
return;
@@ -202,6 +204,24 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq)
spin_unlock_irqrestore(&old->arch.vgic.lock, flags);
}
+void arch_move_irqs(struct vcpu *v)
+{
+ const cpumask_t *cpu_mask = cpumask_of(v->processor);
+ struct domain *d = v->domain;
+ struct pending_irq *p;
+ struct vcpu *v_target;
+ int i;
+
+ for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
+ {
+ v_target = vgic_get_target_vcpu(v, i);
+ p = irq_to_pending(v_target, i);
+
+ if ( v_target == v && !test_bit(GIC_IRQ_GUEST_MIGRATING, &p->status) )
+ irq_set_affinity(p->desc, cpu_mask);
+ }
+}
+
void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
{
struct domain *d = v->domain;
@@ -259,6 +279,7 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
}
if ( p->desc != NULL )
{
+ irq_set_affinity(p->desc, cpumask_of(v_target->processor));
spin_lock_irqsave(&p->desc->lock, flags);
p->desc->handler->enable(p->desc);
spin_unlock_irqrestore(&p->desc->lock, flags);
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index e567f71..e877334 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -42,12 +42,15 @@ void init_secondary_IRQ(void);
int route_irq_to_guest(struct domain *d, unsigned int irq,
const char *devname);
+void arch_move_irqs(struct vcpu *v);
/* Set IRQ type for an SPI */
int irq_set_spi_type(unsigned int spi, unsigned int type);
int platform_get_irq(const struct dt_device_node *device, int index);
+void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask);
+
#endif /* _ASM_HW_IRQ_H */
/*
* Local variables:
diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h
index 9066d38..d3c55f3 100644
--- a/xen/include/asm-x86/irq.h
+++ b/xen/include/asm-x86/irq.h
@@ -197,4 +197,6 @@ void cleanup_domain_irq_mapping(struct domain *);
bool_t cpu_has_pending_apic_eoi(void);
+static inline void arch_move_irqs(struct vcpu *v) { }
+
#endif /* _ASM_HW_IRQ_H */
--
1.7.10.4
next prev parent reply other threads:[~2014-07-24 17:33 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-24 17:31 [PATCH v9 00/10] gic and vgic fixes and improvements Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 01/10] xen/arm: observe itargets setting in vgic_enable_irqs and vgic_disable_irqs Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 02/10] xen/arm: move setting GIC_IRQ_GUEST_QUEUED earlier Stefano Stabellini
2014-07-28 15:16 ` Julien Grall
2014-07-28 16:18 ` Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 03/10] xen/arm: inflight irqs during migration Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 04/10] xen/arm: support irq delivery to vcpu > 0 Stefano Stabellini
2014-07-28 16:16 ` Julien Grall
2014-07-24 17:33 ` Stefano Stabellini [this message]
2014-07-28 15:47 ` [PATCH v9 05/10] xen/arm: physical irq follow virtual irq Julien Grall
2014-07-28 16:20 ` Stefano Stabellini
2014-07-28 16:42 ` Julien Grall
2014-08-01 17:22 ` Stefano Stabellini
2014-08-01 17:54 ` Julien Grall
2014-08-01 17:58 ` Stefano Stabellini
2014-08-01 18:00 ` Julien Grall
2014-07-24 17:33 ` [PATCH v9 06/10] xen: introduce sched_move_irqs Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 07/10] xen: remove workaround to inject evtchn_irq on irq enable Stefano Stabellini
2014-07-25 8:12 ` Jan Beulich
2014-08-01 17:00 ` Stefano Stabellini
2014-08-04 7:15 ` Jan Beulich
2014-08-04 10:02 ` Stefano Stabellini
2014-08-04 10:18 ` Jan Beulich
2014-08-04 20:29 ` Stefano Stabellini
2014-08-05 6:25 ` Jan Beulich
2014-08-05 11:26 ` Stefano Stabellini
2014-07-24 17:33 ` [PATCH v9 08/10] xen/arm: take the rank lock before accessing ipriority Stefano Stabellini
2014-07-28 16:22 ` Julien Grall
2014-07-24 17:33 ` [PATCH v9 09/10] xen: introduce bit access macros for the IRQ line status flags Stefano Stabellini
2014-07-25 12:21 ` Julien Grall
2014-07-24 17:33 ` [PATCH v9 10/10] xen/arm: make accesses to desc->status flags atomic Stefano Stabellini
2014-07-25 12:40 ` Julien Grall
2014-07-28 16:31 ` Stefano Stabellini
2014-07-28 17:14 ` Julien Grall
2014-07-29 10:25 ` Stefano Stabellini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1406223192-26267-5-git-send-email-stefano.stabellini@eu.citrix.com \
--to=stefano.stabellini@eu.citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=julien.grall@citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).