aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros
diff options
context:
space:
mode:
authorTony Zelenoff <antonz@parallels.com>2012-04-13 06:09:54 +0000
committerDavid S. Miller <davem@davemloft.net>2012-04-15 13:00:12 -0400
commit136cd14e1ea2bfde66d212d8e18e81552c94e4e3 (patch)
tree7d0bab86b0a308fa9590fac420da0662ad4adc30 /drivers/net/ethernet/atheros
parentatl1: do not process interrupts in cycle in handler (diff)
downloadlinux-dev-136cd14e1ea2bfde66d212d8e18e81552c94e4e3.tar.xz
linux-dev-136cd14e1ea2bfde66d212d8e18e81552c94e4e3.zip
atl1: do not drop rx/tx interrupts before they are scheduled
To prevent interrupts lost they should be dropped only if they are scheduled via napi interfaces. In other case, there is exists situation when napi handler process TX interrupt, stay in RX processing and in that moment any other interrupt received. Then before this patch TX bit in ISR will be cleaned, napi schedule will not occur in case of currently processing event and TX interrupt definitely will be lost. Signed-off-by: Tony Zelenoff <antonz@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 066b980cc2f0..7f1e498c3c06 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2504,8 +2504,12 @@ static irqreturn_t atl1_intr(int irq, void *data)
if (!status)
return IRQ_NONE;
- /* clear CMB interrupt status at once */
- adapter->cmb.cmb->int_stats = 0;
+ /* clear CMB interrupt status at once,
+ * but leave rx/tx interrupt status in case it should be dropped
+ * only if rx/tx processing queued. In other case interrupt
+ * can be lost.
+ */
+ adapter->cmb.cmb->int_stats = status & (ISR_CMB_TX | ISR_CMB_RX);
if (status & ISR_GPHY) /* clear phy status */
atlx_clear_phy_int(adapter);
@@ -2547,8 +2551,10 @@ static irqreturn_t atl1_intr(int irq, void *data)
}
/* transmit or receive event */
- if (status & (ISR_CMB_TX | ISR_CMB_RX))
- atl1_sched_rings_clean(adapter);
+ if (status & (ISR_CMB_TX | ISR_CMB_RX) &&
+ atl1_sched_rings_clean(adapter))
+ adapter->cmb.cmb->int_stats = adapter->cmb.cmb->int_stats &
+ ~(ISR_CMB_TX | ISR_CMB_RX);
/* rx exception */
if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |