Commit 2772f903 authored by Eilon Greenstein's avatar Eilon Greenstein Committed by David S. Miller

bnx2x: Rx work check

The has Rx work check was wrong: when the FW was at the end of the page,
the driver was already at the beginning of the next page. Since the
check only validated that both driver and FW are pointing to the same
place, it concluded that there is still work to be done. This caused
some serious issues including long latency results on ping-pong test and
lockups while unloading the driver in that condition.
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce3113ec
...@@ -271,7 +271,7 @@ struct bnx2x_fastpath { ...@@ -271,7 +271,7 @@ struct bnx2x_fastpath {
(fp->tx_pkt_prod != fp->tx_pkt_cons)) (fp->tx_pkt_prod != fp->tx_pkt_cons))
#define BNX2X_HAS_RX_WORK(fp) \ #define BNX2X_HAS_RX_WORK(fp) \
(fp->rx_comp_cons != le16_to_cpu(*fp->rx_cons_sb)) (fp->rx_comp_cons != rx_cons_sb)
#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp)) #define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
......
...@@ -9250,6 +9250,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) ...@@ -9250,6 +9250,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
napi); napi);
struct bnx2x *bp = fp->bp; struct bnx2x *bp = fp->bp;
int work_done = 0; int work_done = 0;
u16 rx_cons_sb;
#ifdef BNX2X_STOP_ON_ERROR #ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic)) if (unlikely(bp->panic))
...@@ -9265,10 +9266,16 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) ...@@ -9265,10 +9266,16 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
if (BNX2X_HAS_TX_WORK(fp)) if (BNX2X_HAS_TX_WORK(fp))
bnx2x_tx_int(fp, budget); bnx2x_tx_int(fp, budget);
rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
rx_cons_sb++;
if (BNX2X_HAS_RX_WORK(fp)) if (BNX2X_HAS_RX_WORK(fp))
work_done = bnx2x_rx_int(fp, budget); work_done = bnx2x_rx_int(fp, budget);
rmb(); /* BNX2X_HAS_WORK() reads the status block */ rmb(); /* BNX2X_HAS_WORK() reads the status block */
rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
rx_cons_sb++;
/* must not complete if we consumed full budget */ /* must not complete if we consumed full budget */
if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) { if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment