aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2012-03-21 11:38:33 -0400
committerDavid S. Miller <davem@davemloft.net>2012-03-21 21:57:36 -0400
commit7ae5289017e5ed5514b2603d157fb54c058a3c82 (patch)
tree3ab4c34f95aced979df8ad5e7be721996f5911b1 /drivers/net/ethernet/broadcom/tg3.c
parent5676cc7bfe1e388e87843f71daa229610385b41e (diff)
tg3: Fix RSS ring refill race condition
The RSS feature in tg3 hardware has only one rx producer ring for all RSS rings. NAPI vector 1 is special and handles the refilling of the rx producer ring on behalf of all RSS rings. There is a race condition between these RSS NAPIs and the NAPI[1]. If NAPI[1] finishes checking for refill and then another RSS ring empties the rx producer ring before NAPI[1] exits NAPI, the chip will be completely out of SKBs in the rx producer ring. We fix this by adding a flag tp->rx_refill and rely on napi_schedule()/ napi_complete() to help synchronize it to close the race condition. Update driver version to 3.123. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index b0657466041d..7b71387cf93c 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
89 89
90#define DRV_MODULE_NAME "tg3" 90#define DRV_MODULE_NAME "tg3"
91#define TG3_MAJ_NUM 3 91#define TG3_MAJ_NUM 3
92#define TG3_MIN_NUM 122 92#define TG3_MIN_NUM 123
93#define DRV_MODULE_VERSION \ 93#define DRV_MODULE_VERSION \
94 __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) 94 __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
95#define DRV_MODULE_RELDATE "December 7, 2011" 95#define DRV_MODULE_RELDATE "March 21, 2012"
96 96
97#define RESET_KIND_SHUTDOWN 0 97#define RESET_KIND_SHUTDOWN 0
98#define RESET_KIND_INIT 1 98#define RESET_KIND_INIT 1
@@ -5953,8 +5953,10 @@ next_pkt_nopost:
5953 tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask; 5953 tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask;
5954 tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask; 5954 tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask;
5955 5955
5956 if (tnapi != &tp->napi[1]) 5956 if (tnapi != &tp->napi[1]) {
5957 tp->rx_refill = true;
5957 napi_schedule(&tp->napi[1].napi); 5958 napi_schedule(&tp->napi[1].napi);
5959 }
5958 } 5960 }
5959 5961
5960 return received; 5962 return received;
@@ -6134,6 +6136,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
6134 u32 std_prod_idx = dpr->rx_std_prod_idx; 6136 u32 std_prod_idx = dpr->rx_std_prod_idx;
6135 u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; 6137 u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
6136 6138
6139 tp->rx_refill = false;
6137 for (i = 1; i < tp->irq_cnt; i++) 6140 for (i = 1; i < tp->irq_cnt; i++)
6138 err |= tg3_rx_prodring_xfer(tp, dpr, 6141 err |= tg3_rx_prodring_xfer(tp, dpr,
6139 &tp->napi[i].prodring); 6142 &tp->napi[i].prodring);
@@ -6197,9 +6200,25 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
6197 /* check for RX/TX work to do */ 6200 /* check for RX/TX work to do */
6198 if (likely(sblk->idx[0].tx_consumer == tnapi->tx_cons && 6201 if (likely(sblk->idx[0].tx_consumer == tnapi->tx_cons &&
6199 *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr)) { 6202 *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr)) {
6203
6204 /* This test here is not race free, but will reduce
6205 * the number of interrupts by looping again.
6206 */
6207 if (tnapi == &tp->napi[1] && tp->rx_refill)
6208 continue;
6209
6200 napi_complete(napi); 6210 napi_complete(napi);
6201 /* Reenable interrupts. */ 6211 /* Reenable interrupts. */
6202 tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24); 6212 tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
6213
6214 /* This test here is synchronized by napi_schedule()
6215 * and napi_complete() to close the race condition.
6216 */
6217 if (unlikely(tnapi == &tp->napi[1] && tp->rx_refill)) {
6218 tw32(HOSTCC_MODE, tp->coalesce_mode |
6219 HOSTCC_MODE_ENABLE |
6220 tnapi->coal_now);
6221 }
6203 mmiowb(); 6222 mmiowb();
6204 break; 6223 break;
6205 } 6224 }