bnxt_en: Add a mutex to synchronize ULP operations
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Wed, 1 May 2024 00:30:54 +0000 (17:30 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 2 May 2024 14:27:20 +0000 (07:27 -0700)
The current scheme relies heavily on the RTNL lock for all ULP
operations between the L2 and the RoCE driver.  Add a new en_dev_lock
mutex so that the asynchronous ULP_STOP and ULP_START operations
can be serialized with bnxt_register_dev() and bnxt_unregister_dev()
calls without relying on the RTNL lock.  The next patch will remove
the RTNL lock from the ULP_STOP and ULP_START calls.

Reviewed-by: Selvin Thyparampil Xavier <selvin.xavier@broadcom.com>
Reviewed-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240501003056.100607-5-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h

index d8927838f1cfb4a968e6e70f2a3f0f10de27efe4..ba3fa1c2e5d9ab49cb8c31de1336b6c6627198ab 100644 (file)
@@ -113,6 +113,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev,
        int rc = 0;
 
        rtnl_lock();
+       mutex_lock(&edev->en_dev_lock);
        if (!bp->irq_tbl) {
                rc = -ENODEV;
                goto exit;
@@ -136,6 +137,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev,
        bnxt_fill_msix_vecs(bp, bp->edev->msix_entries);
        edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;
 exit:
+       mutex_unlock(&edev->en_dev_lock);
        rtnl_unlock();
        return rc;
 }
@@ -150,6 +152,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev)
 
        ulp = edev->ulp_tbl;
        rtnl_lock();
+       mutex_lock(&edev->en_dev_lock);
        if (ulp->msix_requested)
                edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED;
        edev->ulp_tbl->msix_requested = 0;
@@ -165,6 +168,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev)
                msleep(100);
                i++;
        }
+       mutex_unlock(&edev->en_dev_lock);
        rtnl_unlock();
        return;
 }
@@ -223,6 +227,12 @@ void bnxt_ulp_stop(struct bnxt *bp)
        if (!edev)
                return;
 
+       mutex_lock(&edev->en_dev_lock);
+       if (!bnxt_ulp_registered(edev)) {
+               mutex_unlock(&edev->en_dev_lock);
+               return;
+       }
+
        edev->flags |= BNXT_EN_FLAG_ULP_STOPPED;
        if (aux_priv) {
                struct auxiliary_device *adev;
@@ -237,6 +247,7 @@ void bnxt_ulp_stop(struct bnxt *bp)
                        adrv->suspend(adev, pm);
                }
        }
+       mutex_unlock(&edev->en_dev_lock);
 }
 
 void bnxt_ulp_start(struct bnxt *bp, int err)
@@ -252,6 +263,12 @@ void bnxt_ulp_start(struct bnxt *bp, int err)
        if (err)
                return;
 
+       mutex_lock(&edev->en_dev_lock);
+       if (!bnxt_ulp_registered(edev)) {
+               mutex_unlock(&edev->en_dev_lock);
+               return;
+       }
+
        if (edev->ulp_tbl->msix_requested)
                bnxt_fill_msix_vecs(bp, edev->msix_entries);
 
@@ -267,7 +284,7 @@ void bnxt_ulp_start(struct bnxt *bp, int err)
                        adrv->resume(adev);
                }
        }
-
+       mutex_unlock(&edev->en_dev_lock);
 }
 
 void bnxt_ulp_irq_stop(struct bnxt *bp)
@@ -383,6 +400,7 @@ static void bnxt_set_edev_info(struct bnxt_en_dev *edev, struct bnxt *bp)
        edev->l2_db_size = bp->db_size;
        edev->l2_db_size_nc = bp->db_size;
        edev->l2_db_offset = bp->db_offset;
+       mutex_init(&edev->en_dev_lock);
 
        if (bp->flags & BNXT_FLAG_ROCEV1_CAP)
                edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP;
index b86baf901a5d999c490469b8ac06d9cbb5582717..4eafe6ec0abfad2c213b4c1601f0080637c87615 100644 (file)
@@ -88,6 +88,9 @@ struct bnxt_en_dev {
 
        u16                             ulp_num_msix_vec;
        u16                             ulp_num_ctxs;
+
+                                       /* serialize ulp operations */
+       struct mutex                    en_dev_lock;
 };
 
 static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev)