aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Bezut <rbezut@gmail.com>2015-09-23 19:31:16 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-10-15 13:17:19 -0400
commita86760664f4cf44c0981ac0c91777eed3a2970e4 (patch)
tree0f9405b37799242b53bed99441e03286bbf873c2
parent10b4ad1a53e40425122a1a8f21f2d7428fa31e08 (diff)
PCI/MSI: Export all remapped MSIs to sysfs attributes
irqbalance uses sysfs attributes to populate its internal database, which is then used to bind the IRQ to the appropriate NUMA node. On a device accepting multiple MSIs and with interrupt remapping enabled, only the first IRQ entry is exported in the "msi_irqs" directory. This results in irqbalance having no clue of the NUMA affinity for the extra IRQs, so it can't bind them to the correct node. Export all MSI interrupts as sysfs attributes when relevant. [bhelgaas: changelog] Signed-off-by: Romain Bezut <rbezut@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/pci/msi.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d4497141d083..324a1643fce2 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -475,10 +475,11 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
475 int ret = -ENOMEM; 475 int ret = -ENOMEM;
476 int num_msi = 0; 476 int num_msi = 0;
477 int count = 0; 477 int count = 0;
478 int i;
478 479
479 /* Determine how many msi entries we have */ 480 /* Determine how many msi entries we have */
480 for_each_pci_msi_entry(entry, pdev) 481 for_each_pci_msi_entry(entry, pdev)
481 ++num_msi; 482 num_msi += entry->nvec_used;
482 if (!num_msi) 483 if (!num_msi)
483 return 0; 484 return 0;
484 485
@@ -487,19 +488,21 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
487 if (!msi_attrs) 488 if (!msi_attrs)
488 return -ENOMEM; 489 return -ENOMEM;
489 for_each_pci_msi_entry(entry, pdev) { 490 for_each_pci_msi_entry(entry, pdev) {
490 msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); 491 for (i = 0; i < entry->nvec_used; i++) {
491 if (!msi_dev_attr) 492 msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);
492 goto error_attrs; 493 if (!msi_dev_attr)
493 msi_attrs[count] = &msi_dev_attr->attr; 494 goto error_attrs;
494 495 msi_attrs[count] = &msi_dev_attr->attr;
495 sysfs_attr_init(&msi_dev_attr->attr); 496
496 msi_dev_attr->attr.name = kasprintf(GFP_KERNEL, "%d", 497 sysfs_attr_init(&msi_dev_attr->attr);
497 entry->irq); 498 msi_dev_attr->attr.name = kasprintf(GFP_KERNEL, "%d",
498 if (!msi_dev_attr->attr.name) 499 entry->irq + i);
499 goto error_attrs; 500 if (!msi_dev_attr->attr.name)
500 msi_dev_attr->attr.mode = S_IRUGO; 501 goto error_attrs;
501 msi_dev_attr->show = msi_mode_show; 502 msi_dev_attr->attr.mode = S_IRUGO;
502 ++count; 503 msi_dev_attr->show = msi_mode_show;
504 ++count;
505 }
503 } 506 }
504 507
505 msi_irq_group = kzalloc(sizeof(*msi_irq_group), GFP_KERNEL); 508 msi_irq_group = kzalloc(sizeof(*msi_irq_group), GFP_KERNEL);