Re: [RFC][PATCH] Add sysfs entry that displays MSI-X IRQs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi again,
Made a few changes based on the feedback. A binary file isn't used anymore. The directory name has changed to reflect exactly what it's displaying. Naming it "interrupts" seemed a little incorrect in this instance since it's only displaying MSI-X interrupts. I have no problem changing the directory name though. The IRQs are now represented by naming each file the IRQ value. The reason for the change was simple, it removed the need for any type of show function or special attribute and does away with the msix prefix since we know it's msix from the directory name.


Cheers,


-- Vinnie.
>From 04b1059375ce146f6d12ac15e183e8d1187f10ce Mon Sep 17 00:00:00 2001
From: Vincent Rizza <vinnie@xxxxxxx>
Date: Thu, 13 Nov 2008 10:27:33 +1100
Subject: [RFC][PATCH] Add sysfs entry that displays MSI-X IRQs

Here's the new patch. It creates an "msix_irq" directory in
/sys/bus/pci/devices/.../ and populates it with a file for each MSI-X
vector used by the device. The filename is the vector number(ie. IRQ).

Exposing the vectors to userspace allows applications like
irqbalancer to intelligently spread device IRQs across many CPUs
since it will be able to work out which IRQ belongs to which device.

Signed-off-by: Vincent Rizza <vinnie@xxxxxxx>
Signed-off-by: Brett Grandbois <brettg@xxxxxxx>
Signed-off-by: Greg Banks <gnb@xxxxxxx>
---
 Documentation/ABI/testing/sysfs-bus-pci |    9 +++++++
 drivers/pci/msi.c                       |   38 +++++++++++++++++++++++++++++++
 include/linux/msi.h                     |    5 ++++
 include/linux/pci.h                     |    1 +
 4 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index ceddcff..4f6f038 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -9,3 +9,12 @@ Description:
 		that some devices may have malformatted data.  If the
 		underlying VPD has a writable section then the
 		corresponding section of this file will be writable.
+
+What:		/sys/bus/pci/devices/.../msix_irq/<IRQ vector number>
+Date:		November 2008
+Contact:	Vincent Rizza <vinnie@xxxxxxx>
+Description:
+		If a pci device uses any MSI-X IRQs a new directory
+		is created called "msix_irq". The directory contains a
+		file for each MSI-X IRQ used. The filename is the IRQ
+		number.
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 74801f7..35dcab6 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -488,12 +488,33 @@ static int msix_capability_init(struct pci_dev *dev,
 		return avail;
 	}
 
+	/* create directory "msix_irq" */
+	dev->msix_dir = kobject_create_and_add("msix_irq", &dev->dev.kobj);
+	if (!dev->msix_dir)
+		return -ENOMEM;
+
 	i = 0;
 	list_for_each_entry(entry, &dev->msi_list, list) {
 		entries[i].vector = entry->irq;
 		set_irq_msi(entry->irq, entry);
+
+		snprintf(entry->msix_fname, sizeof(entry->msix_fname), "%d",
+			 entry->irq);
+		entry->sysfs_entry.attr.name = (const char *) entry->msix_fname;
+		/*  Just so we don't get irrelevant permission errors */
+		entry->sysfs_entry.attr.mode = 0444;
+
+		ret = sysfs_create_file(dev->msix_dir,
+					&entry->sysfs_entry.attr);
+		if (ret) {
+			/* Using name as a flag during clean-up */
+			entry->sysfs_entry.attr.name = NULL;
+			msi_free_irqs(dev);
+			return ret;
+		}
 		i++;
 	}
+
 	/* Set MSI-X enabled bits */
 	pci_intx_for_msi(dev, 0);
 	msix_set_enable(dev, 1);
@@ -641,10 +662,27 @@ static int msi_free_irqs(struct pci_dev* dev)
 			if (list_is_last(&entry->list, &dev->msi_list))
 				iounmap(entry->mask_base);
 		}
+
+		/*
+		 *  Only remove if it's been created. If the attribute's name is
+		 *  set then this particular "entry" corresponds to a sysfs
+		 *  file.
+		 */
+		if (entry->sysfs_entry.attr.name)
+			sysfs_remove_file(&dev->dev.kobj,
+					  &entry->sysfs_entry.attr);
+
 		list_del(&entry->list);
 		kfree(entry);
 	}
 
+	/* Also doesn't exist in MSI mode */
+	if (dev->msix_dir) {
+		sysfs_remove_dir(dev->msix_dir);
+		kobject_put(dev->msix_dir);
+		dev->msix_dir = NULL;
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 8f29392..b0c92d3 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -2,6 +2,7 @@
 #define LINUX_MSI_H
 
 #include <linux/list.h>
+#include <linux/device.h>
 
 struct msi_msg {
 	u32	address_lo;	/* low 32 bits of msi message address */
@@ -33,6 +34,10 @@ struct msi_desc {
 	void __iomem *mask_base;
 	struct pci_dev *dev;
 
+	struct	device_attribute sysfs_entry;
+	/* filename = IRQ */
+	char	msix_fname[16];
+
 	/* Last set MSI message */
 	struct msi_msg msg;
 };
diff --git a/include/linux/pci.h b/include/linux/pci.h
index c75b82b..6b818f7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -234,6 +234,7 @@ struct pci_dev {
 	struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
 #ifdef CONFIG_PCI_MSI
 	struct list_head msi_list;
+	struct kobject *msix_dir;
 #endif
 	struct pci_vpd *vpd;
 };

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux