summaryrefslogtreecommitdiff
path: root/drivers/pci/host/vmd.c
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2018-05-08 10:00:22 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-11-13 11:15:07 -0800
commit635c8c9ce51bcee0902c5a4d2996163e30213320 (patch)
tree4531663966038518560f5013017c184cb4a7f719 /drivers/pci/host/vmd.c
parent2b216de5804f6dac761bbf6667bc707ea1aeb771 (diff)
PCI: vmd: White list for fast interrupt handlers
commit a7f58b9ecfd3c0f63703ec10f4a592cc38dbd1b8 upstream. Devices with slow interrupt handlers are significantly harming performance when their interrupt vector is shared with a fast device. Create a class code white list for devices with known fast interrupt handlers and let all other devices share a single vector so that they don't interfere with performance. At the moment, only the NVM Express class code is on the list, but more may be added if VMD users desire to use other low-latency devices in these domains. Signed-off-by: Keith Busch <keith.busch@intel.com> [lorenzo.pieralisi@arm.com: changelog] Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Jon Derrick: <jonathan.derrick@intel.com> Cc: "Heitke, Kenneth" <kenneth.heitke@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pci/host/vmd.c')
-rw-r--r--drivers/pci/host/vmd.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 509893bc3e63..2537b022f42d 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -183,9 +183,20 @@ static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *d
int i, best = 1;
unsigned long flags;
- if (pci_is_bridge(msi_desc_to_pci_dev(desc)) || vmd->msix_count == 1)
+ if (vmd->msix_count == 1)
return &vmd->irqs[0];
+ /*
+ * White list for fast-interrupt handlers. All others will share the
+ * "slow" interrupt vector.
+ */
+ switch (msi_desc_to_pci_dev(desc)->class) {
+ case PCI_CLASS_STORAGE_EXPRESS:
+ break;
+ default:
+ return &vmd->irqs[0];
+ }
+
raw_spin_lock_irqsave(&list_lock, flags);
for (i = 1; i < vmd->msix_count; i++)
if (vmd->irqs[i].count < vmd->irqs[best].count)