aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_init.c
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2014-03-07 08:40:49 -0500
committerRoland Dreier <roland@purestorage.com>2014-03-17 19:16:51 -0400
commit1ed88dd7d0b361e677b2690f573e5c274bb25c87 (patch)
treed78f5aa8f9983b92b7db9f876817199b136c3a2b /drivers/infiniband/hw/qib/qib_init.c
parentf8b6c47a44c063062317646683a73371c24c69ee (diff)
IB/qib: Add percpu counter replacing qib_devdata int_counter
This patch replaces the dd->int_counter with a percpu counter. The maintanance of qib_stats.sps_ints and int_counter are combined into the new counter. There are two new functions added to read the counter: - qib_int_counter (for a particular qib_devdata) - qib_sps_ints (for all HCAs) A z_int_counter is added to allow the interrupt detection logic to determine if interrupts have occured since z_int_counter was "reset". Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> 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.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 76c3e177164d..6d2629990cb3 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -525,6 +525,7 @@ static void enable_chip(struct qib_devdata *dd)
525static void verify_interrupt(unsigned long opaque) 525static void verify_interrupt(unsigned long opaque)
526{ 526{
527 struct qib_devdata *dd = (struct qib_devdata *) opaque; 527 struct qib_devdata *dd = (struct qib_devdata *) opaque;
528 u64 int_counter;
528 529
529 if (!dd) 530 if (!dd)
530 return; /* being torn down */ 531 return; /* being torn down */
@@ -533,7 +534,8 @@ static void verify_interrupt(unsigned long opaque)
533 * If we don't have a lid or any interrupts, let the user know and 534 * If we don't have a lid or any interrupts, let the user know and
534 * don't bother checking again. 535 * don't bother checking again.
535 */ 536 */
536 if (dd->int_counter == 0) { 537 int_counter = qib_int_counter(dd) - dd->z_int_counter;
538 if (int_counter == 0) {
537 if (!dd->f_intr_fallback(dd)) 539 if (!dd->f_intr_fallback(dd))
538 dev_err(&dd->pcidev->dev, 540 dev_err(&dd->pcidev->dev,
539 "No interrupts detected, not usable.\n"); 541 "No interrupts detected, not usable.\n");
@@ -1079,9 +1081,34 @@ void qib_free_devdata(struct qib_devdata *dd)
1079#ifdef CONFIG_DEBUG_FS 1081#ifdef CONFIG_DEBUG_FS
1080 qib_dbg_ibdev_exit(&dd->verbs_dev); 1082 qib_dbg_ibdev_exit(&dd->verbs_dev);
1081#endif 1083#endif
1084 free_percpu(dd->int_counter);
1082 ib_dealloc_device(&dd->verbs_dev.ibdev); 1085 ib_dealloc_device(&dd->verbs_dev.ibdev);
1083} 1086}
1084 1087
1088u64 qib_int_counter(struct qib_devdata *dd)
1089{
1090 int cpu;
1091 u64 int_counter = 0;
1092
1093 for_each_possible_cpu(cpu)
1094 int_counter += *per_cpu_ptr(dd->int_counter, cpu);
1095 return int_counter;
1096}
1097
1098u64 qib_sps_ints(void)
1099{
1100 unsigned long flags;
1101 struct qib_devdata *dd;
1102 u64 sps_ints = 0;
1103
1104 spin_lock_irqsave(&qib_devs_lock, flags);
1105 list_for_each_entry(dd, &qib_dev_list, list) {
1106 sps_ints += qib_int_counter(dd);
1107 }
1108 spin_unlock_irqrestore(&qib_devs_lock, flags);
1109 return sps_ints;
1110}
1111
1085/* 1112/*
1086 * Allocate our primary per-unit data structure. Must be done via verbs 1113 * Allocate our primary per-unit data structure. Must be done via verbs
1087 * allocator, because the verbs cleanup process both does cleanup and 1114 * allocator, because the verbs cleanup process both does cleanup and
@@ -1119,6 +1146,13 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
1119 "Could not allocate unit ID: error %d\n", -ret); 1146 "Could not allocate unit ID: error %d\n", -ret);
1120 goto bail; 1147 goto bail;
1121 } 1148 }
1149 dd->int_counter = alloc_percpu(u64);
1150 if (!dd->int_counter) {
1151 ret = -ENOMEM;
1152 qib_early_err(&pdev->dev,
1153 "Could not allocate per-cpu int_counter\n");
1154 goto bail;
1155 }
1122 1156
1123 if (!qib_cpulist_count) { 1157 if (!qib_cpulist_count) {
1124 u32 count = num_online_cpus(); 1158 u32 count = num_online_cpus();