[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC v2 01/16] gic:gic-vgic: separate GIV3 code more thoroughly
From: Andrii Anisov <andrii_anisov@xxxxxxxx> This reduces some code and conditions in an IRQ processing path, reducing IRQ latency for a build supported GICV2 only. Signed-off-by: Andrii Anisov <andrii_anisov@xxxxxxxx> --- Its a patch [1] with a better message and removed build errors. Comments from Andre are not addressed yet. [1] https://lists.xenproject.org/archives/html/xen-devel/2018-11/msg03282.html --- xen/arch/arm/gic-vgic.c | 13 ++++++++++++- xen/arch/arm/gic.c | 6 ++++++ xen/arch/arm/vgic.c | 20 ++++++++++++++++++++ xen/arch/arm/vgic/vgic.c | 2 ++ xen/include/asm-arm/irq.h | 2 ++ xen/include/asm-arm/vgic.h | 17 +++++++++++------ 6 files changed, 53 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c index 48922f5..74b5fae 100644 --- a/xen/arch/arm/gic-vgic.c +++ b/xen/arch/arm/gic-vgic.c @@ -36,7 +36,9 @@ static inline void gic_set_lr(int lr, struct pending_irq *p, { ASSERT(!local_irq_is_enabled()); +#ifdef CONFIG_GICV3 clear_bit(GIC_IRQ_GUEST_PRISTINE_LPI, &p->status); +#endif gic_hw_ops->update_lr(lr, p->irq, p->priority, p->desc ? p->desc->irq : INVALID_IRQ, state); @@ -77,9 +79,11 @@ void gic_raise_inflight_irq(struct vcpu *v, unsigned int virtual_irq) { struct pending_irq *n = irq_to_pending(v, virtual_irq); +#ifdef CONFIG_GICV3 /* If an LPI has been removed meanwhile, there is nothing left to raise. */ if ( unlikely(!n) ) return; +#endif ASSERT(spin_is_locked(&v->arch.vgic.lock)); @@ -112,13 +116,14 @@ static unsigned int gic_find_unused_lr(struct vcpu *v, { unsigned int nr_lrs = gic_get_nr_lrs(); unsigned long *lr_mask = (unsigned long *) &this_cpu(lr_mask); - struct gic_lr lr_val; ASSERT(spin_is_locked(&v->arch.vgic.lock)); +#ifdef CONFIG_GICV3 if ( unlikely(test_bit(GIC_IRQ_GUEST_PRISTINE_LPI, &p->status)) ) { unsigned int used_lr; + struct gic_lr lr_val; for_each_set_bit(used_lr, lr_mask, nr_lrs) { @@ -127,6 +132,7 @@ static unsigned int gic_find_unused_lr(struct vcpu *v, return used_lr; } } +#endif lr = find_next_zero_bit(lr_mask, nr_lrs, lr); @@ -142,9 +148,11 @@ void gic_raise_guest_irq(struct vcpu *v, unsigned int virtual_irq, ASSERT(spin_is_locked(&v->arch.vgic.lock)); +#ifdef CONFIG_GICV3 if ( unlikely(!p) ) /* An unmapped LPI does not need to be raised. */ return; +#endif if ( v == current && list_empty(&v->arch.vgic.lr_pending) ) { @@ -172,6 +180,8 @@ static void gic_update_one_lr(struct vcpu *v, int i) gic_hw_ops->read_lr(i, &lr_val); irq = lr_val.virq; p = irq_to_pending(v, irq); + +#ifdef CONFIG_GICV3 /* * An LPI might have been unmapped, in which case we just clean up here. * If that LPI is marked as PRISTINE, the information in the LR is bogus, @@ -188,6 +198,7 @@ static void gic_update_one_lr(struct vcpu *v, int i) return; } +#endif if ( lr_val.active ) { diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 6cc7dec..77fc06f 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -136,7 +136,9 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq, /* Caller has already checked that the IRQ is an SPI */ ASSERT(virq >= 32); ASSERT(virq < vgic_num_irqs(d)); +#ifdef CONFIG_GICV3 ASSERT(!is_lpi(virq)); +#endif /* * When routing an IRQ to guest, the virtual state is not synced @@ -168,7 +170,9 @@ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, ASSERT(spin_is_locked(&desc->lock)); ASSERT(test_bit(_IRQ_GUEST, &desc->status)); +#ifdef CONFIG_GICV3 ASSERT(!is_lpi(virq)); +#endif /* * Removing an interrupt while the domain is running may have @@ -391,6 +395,7 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq) do_IRQ(regs, irq, is_fiq); local_irq_disable(); } +#ifdef CONFIG_GICV3 else if ( is_lpi(irq) ) { local_irq_enable(); @@ -398,6 +403,7 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq) gic_hw_ops->do_LPI(irq); local_irq_disable(); } +#endif else if ( unlikely(irq < 16) ) { do_sgi(regs, irq); diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 255210c..dd35695 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -64,14 +64,18 @@ struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq) void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq) { +#ifdef CONFIG_GICV3 /* The lpi_vcpu_id field must be big enough to hold a VCPU ID. */ BUILD_BUG_ON(BIT(sizeof(p->lpi_vcpu_id) * 8) < MAX_VIRT_CPUS); +#endif memset(p, 0, sizeof(*p)); INIT_LIST_HEAD(&p->inflight); INIT_LIST_HEAD(&p->lr_queue); p->irq = virq; +#ifdef CONFIG_GICV3 p->lpi_vcpu_id = INVALID_VCPU_ID; +#endif } static void vgic_rank_init(struct vgic_irq_rank *rank, uint8_t index, @@ -246,9 +250,11 @@ static int vgic_get_virq_priority(struct vcpu *v, unsigned int virq) { struct vgic_irq_rank *rank; +#ifdef CONFIG_GICV3 /* LPIs don't have a rank, also store their priority separately. */ if ( is_lpi(virq) ) return v->domain->arch.vgic.handler->lpi_get_priority(v->domain, virq); +#endif rank = vgic_rank_irq(v, virq); return ACCESS_ONCE(rank->priority[virq & INTERRUPT_RANK_MASK]); @@ -259,8 +265,10 @@ bool vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) unsigned long flags; struct pending_irq *p; +#ifdef CONFIG_GICV3 /* This will never be called for an LPI, as we don't migrate them. */ ASSERT(!is_lpi(irq)); +#endif spin_lock_irqsave(&old->arch.vgic.lock, flags); @@ -315,6 +323,7 @@ void arch_move_irqs(struct vcpu *v) struct vcpu *v_target; int i; +#ifdef CONFIG_GICV3 /* * We don't migrate LPIs at the moment. * If we ever do, we must make sure that the struct pending_irq does @@ -325,6 +334,7 @@ void arch_move_irqs(struct vcpu *v) * don't participate. */ ASSERT(!is_lpi(vgic_num_irqs(d) - 1)); +#endif for ( i = 32; i < vgic_num_irqs(d); i++ ) { @@ -346,8 +356,10 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) int i = 0; struct vcpu *v_target; +#ifdef CONFIG_GICV3 /* LPIs will never be disabled via this function. */ ASSERT(!is_lpi(32 * n + 31)); +#endif while ( (i = find_next_bit(&mask, 32, i)) < 32 ) { irq = i + (32 * n); @@ -396,8 +408,10 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) struct vcpu *v_target; struct domain *d = v->domain; +#ifdef CONFIG_GICV3 /* LPIs will never be enabled via this function. */ ASSERT(!is_lpi(32 * n + 31)); +#endif while ( (i = find_next_bit(&mask, 32, i)) < 32 ) { irq = i + (32 * n); @@ -493,8 +507,10 @@ struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq) * are used for SPIs; the rests are used for per cpu irqs */ if ( irq < 32 ) n = &v->arch.vgic.pending_irqs[irq]; +#ifdef CONFIG_GICV3 else if ( is_lpi(irq) ) n = v->domain->arch.vgic.handler->lpi_to_pending(v->domain, irq); +#endif else n = &v->domain->arch.vgic.pending_irqs[irq - 32]; return n; @@ -553,12 +569,14 @@ void vgic_inject_irq(struct domain *d, struct vcpu *v, unsigned int virq, spin_lock_irqsave(&v->arch.vgic.lock, flags); n = irq_to_pending(v, virq); +#ifdef CONFIG_GICV3 /* If an LPI has been removed, there is nothing to inject here. */ if ( unlikely(!n) ) { spin_unlock_irqrestore(&v->arch.vgic.lock, flags); return; } +#endif /* vcpu offline */ if ( test_bit(_VPF_down, &v->pause_flags) ) @@ -610,8 +628,10 @@ bool vgic_evtchn_irq_pending(struct vcpu *v) struct pending_irq *p; p = irq_to_pending(v, v->domain->arch.evtchn_irq); +#ifdef CONFIG_GICV3 /* Does not work for LPIs. */ ASSERT(!is_lpi(v->domain->arch.evtchn_irq)); +#endif return list_empty(&p->inflight); } diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c index e2844dc..b8dbdaf 100644 --- a/xen/arch/arm/vgic/vgic.c +++ b/xen/arch/arm/vgic/vgic.c @@ -703,8 +703,10 @@ bool vgic_evtchn_irq_pending(struct vcpu *v) unsigned long flags; bool pending; +#ifdef CONFIG_GICV3 /* Does not work for LPIs. */ ASSERT(!is_lpi(v->domain->arch.evtchn_irq)); +#endif irq = vgic_get_irq(v->domain, v, v->domain->arch.evtchn_irq); spin_lock_irqsave(&irq->irq_lock, flags); diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h index e45d574..4f1ef3c 100644 --- a/xen/include/asm-arm/irq.h +++ b/xen/include/asm-arm/irq.h @@ -63,10 +63,12 @@ struct irq_desc *__irq_to_desc(int irq); void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq); +#ifdef CONFIG_GICV3 static inline bool is_lpi(unsigned int irq) { return irq >= LPI_OFFSET; } +#endif #define domain_pirq_to_irq(d, pirq) (pirq) diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 447d24e..c5cb63f 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -63,27 +63,32 @@ struct pending_irq * GIC_IRQ_GUEST_MIGRATING: the irq is being migrated to a different * vcpu while it is still inflight and on an GICH_LR register on the * old vcpu. - * - * GIC_IRQ_GUEST_PRISTINE_LPI: the IRQ is a newly mapped LPI, which - * has never been in an LR before. This means that any trace of an - * LPI with the same number in an LR must be from an older LPI, which - * has been unmapped before. - * */ #define GIC_IRQ_GUEST_QUEUED 0 #define GIC_IRQ_GUEST_ACTIVE 1 #define GIC_IRQ_GUEST_VISIBLE 2 #define GIC_IRQ_GUEST_ENABLED 3 #define GIC_IRQ_GUEST_MIGRATING 4 +#ifdef CONFIG_GICV3 + /* + * GIC_IRQ_GUEST_PRISTINE_LPI: the IRQ is a newly mapped LPI, which + * has never been in an LR before. This means that any trace of an + * LPI with the same number in an LR must be from an older LPI, which + * has been unmapped before. + * Valid for GICV3 only. + */ #define GIC_IRQ_GUEST_PRISTINE_LPI 5 +#endif unsigned long status; struct irq_desc *desc; /* only set it the irq corresponds to a physical irq */ unsigned int irq; #define GIC_INVALID_LR (uint8_t)~0 uint8_t lr; uint8_t priority; +#ifdef CONFIG_GICV3 uint8_t lpi_priority; /* Caches the priority if this is an LPI. */ uint8_t lpi_vcpu_id; /* The VCPU for an LPI. */ +#endif /* inflight is used to append instances of pending_irq to * vgic.inflight_irqs */ struct list_head inflight; -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |