[ofa-general] [PATCH] core/mthca: Distinguish multiple IB cards in /proc/interrupts

Arputham Benjamin abenjamin at sgi.com
Wed May 13 16:21:47 PDT 2009


When the mthca driver calls request_irq() to allocate interrupt resources, it uses
the fixed device name string "ib_mthca". When multiple IB cards are present in the system,
every instance of the resource is named "ib_mthca" in /proc/interrupts.
This can make it very confusing trying to work out exactly where IB interrupts are going and why.

Summary of changes:

o Added a new IB core API , ib_init_device() that allocates an ib_device struct
  and initializes its device name.
o Added a new field in mthca_dev struct to hold its device (IRQ) name.
o Replaced the call to ib_alloc_device by ib_init_device at mthca device
  init time.
o Modified device name parameter to request_irq() to use the device name 
  allocated by ib_init_device()

Signed-off-by: Arputham Benjamin <abenjamin at sgi.com>

--- a/ofa_kernel-1.4/drivers/infiniband/core/device.c	2008-08-14 16:58:42.962168204 -0700
+++ b/ofa_kernel-1.4/drivers/infiniband/core/device.c	2008-08-14 17:00:31.276257856 -0700
@@ -181,6 +181,40 @@ struct ib_device *ib_alloc_device(size_t
 EXPORT_SYMBOL(ib_alloc_device);
 
 /**
+ * ib_init_device - allocate and initialize an IB device struct
+ * @size:size of structure to allocate
+ * @name:HCA device name
+ *
+ * Low-level drivers should use ib_init_device() to allocate &struct
+ * ib_device and initialize its device name.  @size is the size of
+ * the structure to be allocated, including any private data used by
+ * the low-level driver.
+ * ib_dealloc_device() must be used to free structures allocated with
+ * ib_init_device().
+ */
+struct ib_device *ib_init_device(size_t size, const char *name)
+{
+	int ret = 0;
+	struct ib_device *device;
+
+	device =  (struct ib_device *) ib_alloc_device(size);
+	if (device) {
+		strlcpy(device->name, name, IB_DEVICE_NAME_MAX);
+		if (strchr(device->name, '%')) {
+			mutex_lock(&device_mutex);
+			ret = alloc_name(device->name);
+			mutex_unlock(&device_mutex);
+		}
+	}
+	if (ret) {
+		ib_dealloc_device(device);
+		return  NULL;
+	}
+	return device;
+}
+EXPORT_SYMBOL(ib_init_device);
+
+/**
  * ib_dealloc_device - free an IB device struct
  * @device:structure to free
  *
--- a/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_dev.h	2008-08-14 16:58:42.994168822 -0700
+++ b/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_dev.h	2008-08-14 17:00:31.288258088 -0700
@@ -360,6 +360,7 @@ struct mthca_dev {
 	struct ib_ah         *sm_ah[MTHCA_MAX_PORTS];
 	spinlock_t            sm_lock;
 	u8                    rate[MTHCA_MAX_PORTS];
+	char                  irq_name[MTHCA_NUM_EQ][IB_DEVICE_NAME_MAX];
 };
 
 #ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
--- a/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_eq.c	2008-08-14 16:58:42.994168822 -0700
+++ b/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_eq.c	2008-08-14 17:00:31.304258396 -0700
@@ -860,17 +860,20 @@ int mthca_init_eq_table(struct mthca_dev
 
 	if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
 		static const char *eq_name[] = {
-			[MTHCA_EQ_COMP]  = DRV_NAME " (comp)",
-			[MTHCA_EQ_ASYNC] = DRV_NAME " (async)",
-			[MTHCA_EQ_CMD]   = DRV_NAME " (cmd)"
+			[MTHCA_EQ_COMP]  = " (comp)",
+			[MTHCA_EQ_ASYNC] = " (async)",
+			[MTHCA_EQ_CMD]   = " (cmd)"
 		};
 
 		for (i = 0; i < MTHCA_NUM_EQ; ++i) {
+			strcpy(&dev->irq_name[i][IB_DEVICE_NAME_MAX], dev->ib_dev.name);
+			strcat(&dev->irq_name[i][IB_DEVICE_NAME_MAX], eq_name[i]);
 			err = request_irq(dev->eq_table.eq[i].msi_x_vector,
 					  mthca_is_memfree(dev) ?
 					  mthca_arbel_msi_x_interrupt :
 					  mthca_tavor_msi_x_interrupt,
-					  0, eq_name[i], dev->eq_table.eq + i);
+					  0, &dev->irq_name[i][IB_DEVICE_NAME_MAX],
+					  dev->eq_table.eq + i);
 			if (err)
 				goto err_out_cmd;
 			dev->eq_table.eq[i].have_irq = 1;
--- a/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_main.c	2008-08-14 16:58:42.994168822 -0700
+++ b/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_main.c	2008-08-14 17:03:53.348154342 -0700
@@ -47,6 +47,8 @@
 #include "mthca_memfree.h"
 #include "mthca_wqe.h"
 
+struct ib_device *ib_init_device(size_t size, const char *name);
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver");
 MODULE_LICENSE("Dual BSD/GPL");
@@ -1091,7 +1093,7 @@ static int __mthca_init_one(struct pci_d
 		}
 	}
 
-	mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev);
+	mdev = (struct mthca_dev *) ib_init_device(sizeof *mdev, "mthca%d");
 	if (!mdev) {
 		dev_err(&pdev->dev, "Device struct alloc failed, "
 			"aborting.\n");
--- a/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_provider.c	2008-08-14 16:58:42.998168899 -0700
+++ b/ofa_kernel-1.4/drivers/infiniband/hw/mthca/mthca_provider.c	2008-08-14 17:00:31.336259013 -0700
@@ -1358,7 +1358,6 @@ int mthca_register_device(struct mthca_d
 	if (ret)
 		return ret;
 
-	strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
 	dev->ib_dev.owner                = THIS_MODULE;
 
 	dev->ib_dev.uverbs_abi_ver	 = MTHCA_UVERBS_ABI_VERSION;





More information about the general mailing list