Clear ctrl_pf while holding ctrl_pf_lock for write, but release the
rwsem before waiting for pre-existing RCU readers. The published NULL
already prevents new readers from acquiring the retiring PF, so holding
the writer lock through synchronize_rcu() only stalls sleepable users.

Signed-off-by: Sergey Temerkhanov <[email protected]>
Reviewed-by: Aleksandr Loktionov <[email protected]>
---
 drivers/net/ethernet/intel/ice/ice_ptp.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c 
b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 043a386c2657..e4c7b110016e 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -3379,16 +3379,21 @@ static void ice_ptp_setup_adapter(struct ice_pf *pf)
 
 static void ice_ptp_cleanup_adapter(struct ice_pf *pf)
 {
-       guard(rwsem_write)(&pf->adapter->ctrl_pf_lock);
+       bool synchronize = false;
 
-       /* Zero out adapter->ctrl_pf pointer when the ctrl_pf itself
-        * is being removed to prevent any secondary PFs from accessing
-        * it after it is deleted.
-        */
-       if (ice_get_ctrl_pf(pf) == pf) {
-               rcu_assign_pointer(pf->adapter->ctrl_pf, NULL);
-               synchronize_rcu();
+       scoped_guard(rwsem_write, &pf->adapter->ctrl_pf_lock) {
+               /* Zero out adapter->ctrl_pf pointer when the ctrl_pf itself
+                * is being removed to prevent any secondary PFs from accessing
+                * it after it is deleted.
+                */
+               if (ice_get_ctrl_pf(pf) == pf) {
+                       rcu_assign_pointer(pf->adapter->ctrl_pf, NULL);
+                       synchronize = true;
+               }
        }
+
+       if (synchronize)
+               synchronize_rcu();
 }
 
 static int ice_ptp_setup_pf(struct ice_pf *pf)
-- 
2.53.0

Reply via email to