Commit de21ec44 authored by Kalesh AP's avatar Kalesh AP Committed by Jakub Kicinski

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: default avatarSelvin Thyparampil Xavier <selvin.xavier@broadcom.com>
Reviewed-by: default avatarVikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240501003056.100607-5-michael.chan@broadcom.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f79d7a9f
...@@ -113,6 +113,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev, ...@@ -113,6 +113,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev,
int rc = 0; int rc = 0;
rtnl_lock(); rtnl_lock();
mutex_lock(&edev->en_dev_lock);
if (!bp->irq_tbl) { if (!bp->irq_tbl) {
rc = -ENODEV; rc = -ENODEV;
goto exit; goto exit;
...@@ -136,6 +137,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev, ...@@ -136,6 +137,7 @@ int bnxt_register_dev(struct bnxt_en_dev *edev,
bnxt_fill_msix_vecs(bp, bp->edev->msix_entries); bnxt_fill_msix_vecs(bp, bp->edev->msix_entries);
edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED; edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;
exit: exit:
mutex_unlock(&edev->en_dev_lock);
rtnl_unlock(); rtnl_unlock();
return rc; return rc;
} }
...@@ -150,6 +152,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev) ...@@ -150,6 +152,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev)
ulp = edev->ulp_tbl; ulp = edev->ulp_tbl;
rtnl_lock(); rtnl_lock();
mutex_lock(&edev->en_dev_lock);
if (ulp->msix_requested) if (ulp->msix_requested)
edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED;
edev->ulp_tbl->msix_requested = 0; edev->ulp_tbl->msix_requested = 0;
...@@ -165,6 +168,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev) ...@@ -165,6 +168,7 @@ void bnxt_unregister_dev(struct bnxt_en_dev *edev)
msleep(100); msleep(100);
i++; i++;
} }
mutex_unlock(&edev->en_dev_lock);
rtnl_unlock(); rtnl_unlock();
return; return;
} }
...@@ -223,6 +227,12 @@ void bnxt_ulp_stop(struct bnxt *bp) ...@@ -223,6 +227,12 @@ void bnxt_ulp_stop(struct bnxt *bp)
if (!edev) if (!edev)
return; 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; edev->flags |= BNXT_EN_FLAG_ULP_STOPPED;
if (aux_priv) { if (aux_priv) {
struct auxiliary_device *adev; struct auxiliary_device *adev;
...@@ -237,6 +247,7 @@ void bnxt_ulp_stop(struct bnxt *bp) ...@@ -237,6 +247,7 @@ void bnxt_ulp_stop(struct bnxt *bp)
adrv->suspend(adev, pm); adrv->suspend(adev, pm);
} }
} }
mutex_unlock(&edev->en_dev_lock);
} }
void bnxt_ulp_start(struct bnxt *bp, int err) void bnxt_ulp_start(struct bnxt *bp, int err)
...@@ -252,6 +263,12 @@ void bnxt_ulp_start(struct bnxt *bp, int err) ...@@ -252,6 +263,12 @@ void bnxt_ulp_start(struct bnxt *bp, int err)
if (err) if (err)
return; 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) if (edev->ulp_tbl->msix_requested)
bnxt_fill_msix_vecs(bp, edev->msix_entries); bnxt_fill_msix_vecs(bp, edev->msix_entries);
...@@ -267,7 +284,7 @@ void bnxt_ulp_start(struct bnxt *bp, int err) ...@@ -267,7 +284,7 @@ void bnxt_ulp_start(struct bnxt *bp, int err)
adrv->resume(adev); adrv->resume(adev);
} }
} }
mutex_unlock(&edev->en_dev_lock);
} }
void bnxt_ulp_irq_stop(struct bnxt *bp) 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) ...@@ -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 = bp->db_size;
edev->l2_db_size_nc = bp->db_size; edev->l2_db_size_nc = bp->db_size;
edev->l2_db_offset = bp->db_offset; edev->l2_db_offset = bp->db_offset;
mutex_init(&edev->en_dev_lock);
if (bp->flags & BNXT_FLAG_ROCEV1_CAP) if (bp->flags & BNXT_FLAG_ROCEV1_CAP)
edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP;
......
...@@ -88,6 +88,9 @@ struct bnxt_en_dev { ...@@ -88,6 +88,9 @@ struct bnxt_en_dev {
u16 ulp_num_msix_vec; u16 ulp_num_msix_vec;
u16 ulp_num_ctxs; u16 ulp_num_ctxs;
/* serialize ulp operations */
struct mutex en_dev_lock;
}; };
static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev) static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment