diff options
author | Mike Marciniszyn <mike.marciniszyn@intel.com> | 2013-05-30 18:25:25 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-06-21 17:19:38 -0700 |
commit | 8469ba39a6b77917e8879680aed17229bf72f263 (patch) | |
tree | f064dfaf3387f3ed5d59d69941b90825fe628729 /drivers/infiniband/hw/qib/qib_init.c | |
parent | fedaf4ffc224a194e2d13a3ec2abe5df0bc94258 (diff) | |
download | linux-8469ba39a6b77917e8879680aed17229bf72f263.tar.gz linux-8469ba39a6b77917e8879680aed17229bf72f263.tar.bz2 linux-8469ba39a6b77917e8879680aed17229bf72f263.zip |
IB/qib: Add DCA support
This patch adds DCA cache warming for systems that support DCA.
The code uses cpu affinity notification to react to an affinity change
from a user mode program like irqbalance and (re-)program the chip
accordingly. This notification avoids reading the current cpu on every
interrupt.
Reviewed-by: Dean Luick <dean.luick@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
[ Add Kconfig dependency on SMP && GENERIC_HARDIRQS to avoid failure to
build due to undefined struct irq_affinity_notify. - Roland ]
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_init.c')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_init.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 173f805790da..4b64c885fa0d 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -39,6 +39,9 @@ #include <linux/idr.h> #include <linux/module.h> #include <linux/printk.h> +#ifdef CONFIG_INFINIBAND_QIB_DCA +#include <linux/dca.h> +#endif #include "qib.h" #include "qib_common.h" @@ -1158,6 +1161,35 @@ struct pci_driver qib_driver = { .err_handler = &qib_pci_err_handler, }; +#ifdef CONFIG_INFINIBAND_QIB_DCA + +static int qib_notify_dca(struct notifier_block *, unsigned long, void *); +static struct notifier_block dca_notifier = { + .notifier_call = qib_notify_dca, + .next = NULL, + .priority = 0 +}; + +static int qib_notify_dca_device(struct device *device, void *data) +{ + struct qib_devdata *dd = dev_get_drvdata(device); + unsigned long event = *(unsigned long *)data; + + return dd->f_notify_dca(dd, event); +} + +static int qib_notify_dca(struct notifier_block *nb, unsigned long event, + void *p) +{ + int rval; + + rval = driver_for_each_device(&qib_driver.driver, NULL, + &event, qib_notify_dca_device); + return rval ? NOTIFY_BAD : NOTIFY_DONE; +} + +#endif + /* * Do all the generic driver unit- and chip-independent memory * allocation and initialization. @@ -1182,6 +1214,9 @@ static int __init qlogic_ib_init(void) */ idr_init(&qib_unit_table); +#ifdef CONFIG_INFINIBAND_QIB_DCA + dca_register_notify(&dca_notifier); +#endif ret = pci_register_driver(&qib_driver); if (ret < 0) { pr_err("Unable to register driver: error %d\n", -ret); @@ -1194,6 +1229,9 @@ static int __init qlogic_ib_init(void) goto bail; /* all OK */ bail_unit: +#ifdef CONFIG_INFINIBAND_QIB_DCA + dca_unregister_notify(&dca_notifier); +#endif idr_destroy(&qib_unit_table); destroy_workqueue(qib_cq_wq); bail_dev: @@ -1217,6 +1255,9 @@ static void __exit qlogic_ib_cleanup(void) "Unable to cleanup counter filesystem: error %d\n", -ret); +#ifdef CONFIG_INFINIBAND_QIB_DCA + dca_unregister_notify(&dca_notifier); +#endif pci_unregister_driver(&qib_driver); destroy_workqueue(qib_cq_wq); |