bnxt_en: Fix MSIX request logic for RDMA driver.
authorMichael Chan <michael.chan@broadcom.com>
Tue, 10 Dec 2019 07:49:07 +0000 (02:49 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Dec 2019 01:37:14 +0000 (17:37 -0800)
The logic needs to check both bp->total_irqs and the reserved IRQs in
hw_resc->resv_irqs if applicable and see if both are enough to cover
the L2 and RDMA requested vectors.  The current code is only checking
bp->total_irqs and can fail in some code paths, such as the TX timeout
code path with the RDMA driver requesting vectors after recovery.  In
this code path, we have not reserved enough MSIX resources for the
RDMA driver yet.

Fixes: 75720e6323a1 ("bnxt_en: Keep track of reserved IRQs.")
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c

index c601ff7b8f61cdde62177430af3e2c61f481dd6a..4a316c4b3fa80d31b4bc0f8546e9ed291bdabd2b 100644 (file)
@@ -113,8 +113,10 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
 {
        struct net_device *dev = edev->net;
        struct bnxt *bp = netdev_priv(dev);
+       struct bnxt_hw_resc *hw_resc;
        int max_idx, max_cp_rings;
        int avail_msix, idx;
+       int total_vecs;
        int rc = 0;
 
        ASSERT_RTNL();
@@ -142,7 +144,10 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
        }
        edev->ulp_tbl[ulp_id].msix_base = idx;
        edev->ulp_tbl[ulp_id].msix_requested = avail_msix;
-       if (bp->total_irqs < (idx + avail_msix)) {
+       hw_resc = &bp->hw_resc;
+       total_vecs = idx + avail_msix;
+       if (bp->total_irqs < total_vecs ||
+           (BNXT_NEW_RM(bp) && hw_resc->resv_irqs < total_vecs)) {
                if (netif_running(dev)) {
                        bnxt_close_nic(bp, true, false);
                        rc = bnxt_open_nic(bp, true, false);
@@ -156,7 +161,6 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
        }
 
        if (BNXT_NEW_RM(bp)) {
-               struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
                int resv_msix;
 
                resv_msix = hw_resc->resv_irqs - bp->cp_nr_rings;