ice: Avoid RTNL lock when re-creating auxiliary device
authorDave Ertman <david.m.ertman@intel.com>
Fri, 21 Jan 2022 00:27:56 +0000 (16:27 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Feb 2022 11:56:32 +0000 (12:56 +0100)
[ Upstream commit 5dbbbd01cbba831233c6ea9a3e6bfa133606d3c0 ]

If a call to re-create the auxiliary device happens in a context that has
already taken the RTNL lock, then the call flow that recreates auxiliary
device can hang if there is another attempt to claim the RTNL lock by the
auxiliary driver.

To avoid this, any call to re-create auxiliary devices that comes from
an source that is holding the RTNL lock (e.g. netdev notifier when
interface exits a bond) should execute in a separate thread.  To
accomplish this, add a flag to the PF that will be evaluated in the
service task and dealt with there.

Fixes: f9f5301e7e2d ("ice: Register auxiliary device to provide RDMA")
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Reviewed-by: Jonathan Toppins <jtoppins@redhat.com>
Tested-by: Gurucharan G <gurucharanx.g@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_main.c

index fba8f021c397de72766c6fd70db2a003a9fae1b0..d119812755b7a0d821254c56b071caee1fae6d15 100644 (file)
@@ -398,6 +398,7 @@ enum ice_pf_flags {
        ICE_FLAG_VF_TRUE_PROMISC_ENA,
        ICE_FLAG_MDD_AUTO_RESET_VF,
        ICE_FLAG_LINK_LENIENT_MODE_ENA,
+       ICE_FLAG_PLUG_AUX_DEV,
        ICE_PF_FLAGS_NBITS              /* must be last */
 };
 
@@ -692,7 +693,7 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)
        if (pf->hw.func_caps.common_cap.rdma && pf->num_rdma_msix) {
                set_bit(ICE_FLAG_RDMA_ENA, pf->flags);
                set_bit(ICE_FLAG_AUX_ENA, pf->flags);
-               ice_plug_aux_dev(pf);
+               set_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags);
        }
 }
 
index cfddec96c91c1c354ce1f0f5f6cb121ed110100c..ab2dea0d2c1aed8f1628c6bf20469b254d434f34 100644 (file)
@@ -2141,6 +2141,9 @@ static void ice_service_task(struct work_struct *work)
                return;
        }
 
+       if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
+               ice_plug_aux_dev(pf);
+
        ice_clean_adminq_subtask(pf);
        ice_check_media_subtask(pf);
        ice_check_for_hang_subtask(pf);