bnxt_en: Add a mutex to synchronize ULP operations
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>
This commit is contained in:
committed by
Jakub Kicinski
parent
f79d7a9f1c
commit
de21ec442d
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user