diff options
author | Mike Marciniszyn <mike.marciniszyn@intel.com> | 2014-03-07 08:40:49 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-03-17 19:16:51 -0400 |
commit | 1ed88dd7d0b361e677b2690f573e5c274bb25c87 (patch) | |
tree | d78f5aa8f9983b92b7db9f876817199b136c3a2b /drivers/infiniband/hw/qib/qib_init.c | |
parent | f8b6c47a44c063062317646683a73371c24c69ee (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.c | 36 |
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) | |||
525 | static void verify_interrupt(unsigned long opaque) | 525 | static 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 | ||
1088 | u64 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 | |||
1098 | u64 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(); |