aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorDave Olson <dave.olson@qlogic.com>2007-07-20 15:50:55 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-30 16:16:45 -0400
commitf17fddc9e266281bbb4d384b031e1521e1f2510e (patch)
tree91f7a4d1ddc4cbb3b7196f50f2b4881ef78522bd /drivers/infiniband
parent1655fc2e12ed7d208403c043428291b83aa833bb (diff)
IB/ipath: Remove unsafe fastrcvint code from interrupt handler
The fastrcvint code's purpose was to avoid reading the interrupt status if kernel packets were in the receive queue (to reduce overhead). Because intstatus was not read, we could miss the error interrupt bit indicating freeze mode, since it only delivers a single interrupt, even if still pending after intclear is written. This patch removes that unsafe optimization. Signed-off-by: Dave Olson <dave.olson@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c32
2 files changed, 1 insertions, 34 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index b4b786d0dfca..6ad822c35930 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -100,8 +100,7 @@ struct infinipath_stats {
100 __u64 sps_hwerrs; 100 __u64 sps_hwerrs;
101 /* number of times IB link changed state unexpectedly */ 101 /* number of times IB link changed state unexpectedly */
102 __u64 sps_iblink; 102 __u64 sps_iblink;
103 /* kernel receive interrupts that didn't read intstat */ 103 __u64 sps_unused; /* was fastrcvint, no longer implemented */
104 __u64 sps_fastrcvint;
105 /* number of kernel (port0) packets received */ 104 /* number of kernel (port0) packets received */
106 __u64 sps_port0pkts; 105 __u64 sps_port0pkts;
107 /* number of "ethernet" packets sent by driver */ 106 /* number of "ethernet" packets sent by driver */
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 1fd91c59f246..cba2041bb0b1 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -1002,7 +1002,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1002 u32 istat, chk0rcv = 0; 1002 u32 istat, chk0rcv = 0;
1003 ipath_err_t estat = 0; 1003 ipath_err_t estat = 0;
1004 irqreturn_t ret; 1004 irqreturn_t ret;
1005 u32 oldhead, curtail;
1006 static unsigned unexpected = 0; 1005 static unsigned unexpected = 0;
1007 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | 1006 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
1008 (1U<<INFINIPATH_I_RCVURG_SHIFT); 1007 (1U<<INFINIPATH_I_RCVURG_SHIFT);
@@ -1035,36 +1034,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1035 goto bail; 1034 goto bail;
1036 } 1035 }
1037 1036
1038 /*
1039 * We try to avoid reading the interrupt status register, since
1040 * that's a PIO read, and stalls the processor for up to about
1041 * ~0.25 usec. The idea is that if we processed a port0 packet,
1042 * we blindly clear the port 0 receive interrupt bits, and nothing
1043 * else, then return. If other interrupts are pending, the chip
1044 * will re-interrupt us as soon as we write the intclear register.
1045 * We then won't process any more kernel packets (if not the 2nd
1046 * time, then the 3rd or 4th) and we'll then handle the other
1047 * interrupts. We clear the interrupts first so that we don't
1048 * lose intr for later packets that arrive while we are processing.
1049 */
1050 oldhead = dd->ipath_port0head;
1051 curtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
1052 if (oldhead != curtail) {
1053 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1054 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
1055 (u64) (1 << IPATH_GPIO_PORT0_BIT));
1056 istat = port0rbits | INFINIPATH_I_GPIO;
1057 }
1058 else
1059 istat = port0rbits;
1060 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
1061 ipath_kreceive(dd);
1062 if (oldhead != dd->ipath_port0head) {
1063 ipath_stats.sps_fastrcvint++;
1064 goto done;
1065 }
1066 }
1067
1068 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); 1037 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
1069 1038
1070 if (unlikely(!istat)) { 1039 if (unlikely(!istat)) {
@@ -1225,7 +1194,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1225 handle_layer_pioavail(dd); 1194 handle_layer_pioavail(dd);
1226 } 1195 }
1227 1196
1228done:
1229 ret = IRQ_HANDLED; 1197 ret = IRQ_HANDLED;
1230 1198
1231bail: 1199bail: