| From 4327ba435a56ada13eedf3eb332e583c7a0586a9 Mon Sep 17 00:00:00 2001 |
| From: Benjamin Li <benli@broadcom.com> |
| Date: Tue, 23 Mar 2010 13:13:11 +0000 |
| Subject: bnx2: Fix netpoll crash. |
| |
| From: Benjamin Li <benli@broadcom.com> |
| |
| commit 4327ba435a56ada13eedf3eb332e583c7a0586a9 upstream. |
| |
| The bnx2 driver calls netif_napi_add() for all the NAPI structs during |
| ->probe() time but not all of them will be used if we're not in MSI-X |
| mode. This creates a problem for netpoll since it will poll all the |
| NAPI structs in the dev_list whether or not they are scheduled, resulting |
| in a crash when we access structure fields not initialized for that vector. |
| |
| We fix it by moving the netif_napi_add() call to ->open() after the number |
| of IRQ vectors has been determined. |
| |
| Signed-off-by: Benjamin Li <benli@broadcom.com> |
| Signed-off-by: Michael Chan <mchan@broadcom.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/bnx2.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/bnx2.c |
| +++ b/drivers/net/bnx2.c |
| @@ -247,6 +247,8 @@ static const struct flash_spec flash_570 |
| |
| MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); |
| |
| +static void bnx2_init_napi(struct bnx2 *bp); |
| + |
| static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) |
| { |
| u32 diff; |
| @@ -6173,6 +6175,7 @@ bnx2_open(struct net_device *dev) |
| bnx2_disable_int(bp); |
| |
| bnx2_setup_int_mode(bp, disable_msi); |
| + bnx2_init_napi(bp); |
| bnx2_napi_enable(bp); |
| rc = bnx2_alloc_mem(bp); |
| if (rc) |
| @@ -8021,7 +8024,7 @@ bnx2_init_napi(struct bnx2 *bp) |
| { |
| int i; |
| |
| - for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { |
| + for (i = 0; i < bp->irq_nvecs; i++) { |
| struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; |
| int (*poll)(struct napi_struct *, int); |
| |
| @@ -8090,7 +8093,6 @@ bnx2_init_one(struct pci_dev *pdev, cons |
| dev->ethtool_ops = &bnx2_ethtool_ops; |
| |
| bp = netdev_priv(dev); |
| - bnx2_init_napi(bp); |
| |
| pci_set_drvdata(pdev, dev); |
| |