Skip to content

Commit

Permalink
bnxt_en: Fix TX timeout during netpoll.
Browse files Browse the repository at this point in the history
The current netpoll implementation in the bnxt_en driver has problems
that may miss TX completion events.  bnxt_poll_work() in effect is
only handling at most 1 TX packet before exiting.  In addition,
there may be in flight TX completions that ->poll() may miss even
after we fix bnxt_poll_work() to handle all visible TX completions.
netpoll may not call ->poll() again and HW may not generate IRQ
because the driver does not ARM the IRQ when the budget (0 for netpoll)
is reached.

We fix it by handling all TX completions and to always ARM the IRQ
when we exit ->poll() with 0 budget.

Also, the logic to ACK the completion ring in case it is almost filled
with TX completions need to be adjusted to take care of the 0 budget
case, as discussed with Eric Dumazet <[email protected]>

Reported-by: Song Liu <[email protected]>
Reviewed-by: Song Liu <[email protected]>
Tested-by: Song Liu <[email protected]>
Signed-off-by: Michael Chan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Michael Chan authored and davem330 committed Sep 27, 2018
1 parent 8fd7806 commit 73f21c6
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,8 +1884,11 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
if (TX_CMP_TYPE(txcmp) == CMP_TYPE_TX_L2_CMP) {
tx_pkts++;
/* return full budget so NAPI will complete. */
if (unlikely(tx_pkts > bp->tx_wake_thresh))
if (unlikely(tx_pkts > bp->tx_wake_thresh)) {
rx_pkts = budget;
raw_cons = NEXT_RAW_CMP(raw_cons);
break;
}
} else if ((TX_CMP_TYPE(txcmp) & 0x30) == 0x10) {
if (likely(budget))
rc = bnxt_rx_pkt(bp, bnapi, &raw_cons, &event);
Expand Down Expand Up @@ -1913,7 +1916,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
}
raw_cons = NEXT_RAW_CMP(raw_cons);

if (rx_pkts == budget)
if (rx_pkts && rx_pkts == budget)
break;
}

Expand Down Expand Up @@ -2027,8 +2030,12 @@ static int bnxt_poll(struct napi_struct *napi, int budget)
while (1) {
work_done += bnxt_poll_work(bp, bnapi, budget - work_done);

if (work_done >= budget)
if (work_done >= budget) {
if (!budget)
BNXT_CP_DB_REARM(cpr->cp_doorbell,
cpr->cp_raw_cons);
break;
}

if (!bnxt_has_work(bp, cpr)) {
if (napi_complete_done(napi, work_done))
Expand Down

0 comments on commit 73f21c6

Please sign in to comment.