提交 f17fddc9 编写于 作者: D Dave Olson 提交者: Roland Dreier

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: NDave Olson <dave.olson@qlogic.com>
Signed-off-by: NRoland Dreier <rolandd@cisco.com>
上级 1655fc2e
...@@ -100,8 +100,7 @@ struct infinipath_stats { ...@@ -100,8 +100,7 @@ struct infinipath_stats {
__u64 sps_hwerrs; __u64 sps_hwerrs;
/* number of times IB link changed state unexpectedly */ /* number of times IB link changed state unexpectedly */
__u64 sps_iblink; __u64 sps_iblink;
/* kernel receive interrupts that didn't read intstat */ __u64 sps_unused; /* was fastrcvint, no longer implemented */
__u64 sps_fastrcvint;
/* number of kernel (port0) packets received */ /* number of kernel (port0) packets received */
__u64 sps_port0pkts; __u64 sps_port0pkts;
/* number of "ethernet" packets sent by driver */ /* number of "ethernet" packets sent by driver */
......
...@@ -1002,7 +1002,6 @@ irqreturn_t ipath_intr(int irq, void *data) ...@@ -1002,7 +1002,6 @@ irqreturn_t ipath_intr(int irq, void *data)
u32 istat, chk0rcv = 0; u32 istat, chk0rcv = 0;
ipath_err_t estat = 0; ipath_err_t estat = 0;
irqreturn_t ret; irqreturn_t ret;
u32 oldhead, curtail;
static unsigned unexpected = 0; static unsigned unexpected = 0;
static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
(1U<<INFINIPATH_I_RCVURG_SHIFT); (1U<<INFINIPATH_I_RCVURG_SHIFT);
...@@ -1035,36 +1034,6 @@ irqreturn_t ipath_intr(int irq, void *data) ...@@ -1035,36 +1034,6 @@ irqreturn_t ipath_intr(int irq, void *data)
goto bail; goto bail;
} }
/*
* We try to avoid reading the interrupt status register, since
* that's a PIO read, and stalls the processor for up to about
* ~0.25 usec. The idea is that if we processed a port0 packet,
* we blindly clear the port 0 receive interrupt bits, and nothing
* else, then return. If other interrupts are pending, the chip
* will re-interrupt us as soon as we write the intclear register.
* We then won't process any more kernel packets (if not the 2nd
* time, then the 3rd or 4th) and we'll then handle the other
* interrupts. We clear the interrupts first so that we don't
* lose intr for later packets that arrive while we are processing.
*/
oldhead = dd->ipath_port0head;
curtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
if (oldhead != curtail) {
if (dd->ipath_flags & IPATH_GPIO_INTR) {
ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
(u64) (1 << IPATH_GPIO_PORT0_BIT));
istat = port0rbits | INFINIPATH_I_GPIO;
}
else
istat = port0rbits;
ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
ipath_kreceive(dd);
if (oldhead != dd->ipath_port0head) {
ipath_stats.sps_fastrcvint++;
goto done;
}
}
istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
if (unlikely(!istat)) { if (unlikely(!istat)) {
...@@ -1225,7 +1194,6 @@ irqreturn_t ipath_intr(int irq, void *data) ...@@ -1225,7 +1194,6 @@ irqreturn_t ipath_intr(int irq, void *data)
handle_layer_pioavail(dd); handle_layer_pioavail(dd);
} }
done:
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
bail: bail:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册