]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bnxt_en: Fix possible BUG() condition when calling pci_disable_msix().
authorMichael Chan <michael.chan@broadcom.com>
Wed, 22 May 2019 23:12:55 +0000 (19:12 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 May 2019 01:02:14 +0000 (18:02 -0700)
When making configuration changes, the driver calls bnxt_close_nic()
and then bnxt_open_nic() for the changes to take effect.  A parameter
irq_re_init is passed to the call sequence to indicate if IRQ
should be re-initialized.  This irq_re_init parameter needs to
be included in the bnxt_reserve_rings() call.  bnxt_reserve_rings()
can only call pci_disable_msix() if the irq_re_init parameter is
true, otherwise it may hit BUG() because some IRQs may not have been
freed yet.

Fixes: 41e8d7983752 ("bnxt_en: Modify the ring reservation functions for 57500 series chips.")
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c

index 21f682610e6ac6e5d5026911850c2828555ca315..cfcc33c52685eb9775ab707024510c4602ec2206 100644 (file)
@@ -7618,22 +7618,23 @@ static void bnxt_clear_int_mode(struct bnxt *bp)
        bp->flags &= ~BNXT_FLAG_USING_MSIX;
 }
 
-int bnxt_reserve_rings(struct bnxt *bp)
+int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
 {
        int tcs = netdev_get_num_tc(bp->dev);
-       bool reinit_irq = false;
+       bool irq_cleared = false;
        int rc;
 
        if (!bnxt_need_reserve_rings(bp))
                return 0;
 
-       if (BNXT_NEW_RM(bp) && (bnxt_get_num_msix(bp) != bp->total_irqs)) {
+       if (irq_re_init && BNXT_NEW_RM(bp) &&
+           bnxt_get_num_msix(bp) != bp->total_irqs) {
                bnxt_ulp_irq_stop(bp);
                bnxt_clear_int_mode(bp);
-               reinit_irq = true;
+               irq_cleared = true;
        }
        rc = __bnxt_reserve_rings(bp);
-       if (reinit_irq) {
+       if (irq_cleared) {
                if (!rc)
                        rc = bnxt_init_int_mode(bp);
                bnxt_ulp_irq_restart(bp, rc);
@@ -8532,7 +8533,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
                        return rc;
                }
        }
-       rc = bnxt_reserve_rings(bp);
+       rc = bnxt_reserve_rings(bp, irq_re_init);
        if (rc)
                return rc;
        if ((bp->flags & BNXT_FLAG_RFS) &&
index eca36dd6b751ee5c37569d2f5d2229a435914ad9..acc73f3017835e486400781293df092a6852bbb3 100644 (file)
@@ -1790,7 +1790,7 @@ unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp);
 unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
 unsigned int bnxt_get_avail_cp_rings_for_en(struct bnxt *bp);
 int bnxt_get_avail_msix(struct bnxt *bp, int num);
-int bnxt_reserve_rings(struct bnxt *bp);
+int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
 void bnxt_tx_disable(struct bnxt *bp);
 void bnxt_tx_enable(struct bnxt *bp);
 int bnxt_hwrm_set_pause(struct bnxt *);
index b1263821a6e9d757a08a4475f0092b0d79f4d775..a6c7baf38036a27fdb2335b64bc07adcdffb280a 100644 (file)
@@ -831,7 +831,7 @@ static int bnxt_set_channels(struct net_device *dev,
                         */
                }
        } else {
-               rc = bnxt_reserve_rings(bp);
+               rc = bnxt_reserve_rings(bp, true);
        }
 
        return rc;
index cf475873ce81c6d191118692e0a57268e770589f..bfa342a98d0812de0091c4b00c9a735da0e0b34d 100644 (file)
@@ -147,7 +147,7 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
                        bnxt_close_nic(bp, true, false);
                        rc = bnxt_open_nic(bp, true, false);
                } else {
-                       rc = bnxt_reserve_rings(bp);
+                       rc = bnxt_reserve_rings(bp, true);
                }
        }
        if (rc) {