Skip to content

Commit a47dee5

Browse files
author
Marc Zyngier
committed
KVM: arm64: Allow in-atomic injection of SPIs
On a system that uses SPIs to implement MSIs (as it would be the case on a GICv2 system exposing a GICv2m to its guests), we deny the possibility of injecting SPIs on the in-atomic fast-path. This results in a very large amount of context-switches (roughly equivalent to twice the interrupt rate) on the host, and suboptimal performance for the guest (as measured with a test workload involving a virtio interface backed by vhost-net). Given that GICv2 systems are usually on the low-end of the spectrum performance wise, they could do without the aggravation. We solved this for GICv3+ITS by having a translation cache. But SPIs do not need any extra infrastructure, and can be immediately injected in the virtual distributor as the locking is already heavy enough that we don't need to worry about anything. This halves the number of context switches for the same workload. Reviewed-by: Eric Auger <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent b3a9e3b commit a47dee5

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

arch/arm64/kvm/vgic/vgic-irqfd.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,33 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
100100

101101
/**
102102
* kvm_arch_set_irq_inatomic: fast-path for irqfd injection
103-
*
104-
* Currently only direct MSI injection is supported.
105103
*/
106104
int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
107105
struct kvm *kvm, int irq_source_id, int level,
108106
bool line_status)
109107
{
110-
if (e->type == KVM_IRQ_ROUTING_MSI && vgic_has_its(kvm) && level) {
108+
if (!level)
109+
return -EWOULDBLOCK;
110+
111+
switch (e->type) {
112+
case KVM_IRQ_ROUTING_MSI: {
111113
struct kvm_msi msi;
112114

115+
if (!vgic_has_its(kvm))
116+
break;
117+
113118
kvm_populate_msi(e, &msi);
114-
if (!vgic_its_inject_cached_translation(kvm, &msi))
115-
return 0;
119+
return vgic_its_inject_cached_translation(kvm, &msi);
120+
}
121+
122+
case KVM_IRQ_ROUTING_IRQCHIP:
123+
/*
124+
* Injecting SPIs is always possible in atomic context
125+
* as long as the damn vgic is initialized.
126+
*/
127+
if (unlikely(!vgic_initialized(kvm)))
128+
break;
129+
return vgic_irqfd_set_irq(e, kvm, irq_source_id, 1, line_status);
116130
}
117131

118132
return -EWOULDBLOCK;

arch/arm64/kvm/vgic/vgic-its.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,8 @@ int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi)
757757

758758
db = (u64)msi->address_hi << 32 | msi->address_lo;
759759
irq = vgic_its_check_cache(kvm, db, msi->devid, msi->data);
760-
761760
if (!irq)
762-
return -1;
761+
return -EWOULDBLOCK;
763762

764763
raw_spin_lock_irqsave(&irq->irq_lock, flags);
765764
irq->pending_latch = true;

0 commit comments

Comments
 (0)