Skip to content

Commit

Permalink
[BNX2]: Refine napi poll loop.
Browse files Browse the repository at this point in the history
Need to read and store sblk->status_idx before checking for more work.
The status idx is later written back to the hardware when enabling
interrupts to acknowledge how much work has been processed.  If the
order is reversed, we can end up acknowledging work we haven't
processed.

When completing bnx2_poll(), we should always break out of the while
loop and return work_done instead of returning 0.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Oct 12, 2007
1 parent 4fd7ab5 commit 6dee642
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2652,10 +2652,10 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget)
REG_RD(bp, BNX2_HC_COMMAND);
}

if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
bnx2_tx_int(bp);

if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
if (sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
work_done += bnx2_rx_int(bp, budget - work_done);

return work_done;
Expand All @@ -2665,23 +2665,27 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
{
struct bnx2 *bp = container_of(napi, struct bnx2, napi);
int work_done = 0;
struct status_block *sblk = bp->status_blk;

while (1) {
work_done = bnx2_poll_work(bp, work_done, budget);

if (unlikely(work_done >= budget))
break;

/* bp->last_status_idx is used below to tell the hw how
* much work has been processed, so we must read it before
* checking for more work.
*/
bp->last_status_idx = sblk->status_idx;
rmb();
if (likely(!bnx2_has_work(bp))) {
bp->last_status_idx = bp->status_blk->status_idx;
rmb();

netif_rx_complete(bp->dev, napi);
if (likely(bp->flags & USING_MSI_FLAG)) {
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
bp->last_status_idx);
return 0;
break;
}
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
Expand Down

0 comments on commit 6dee642

Please sign in to comment.