Skip to content

Commit 248401c

Browse files
dmertmankuba-moo
authored andcommitted
ice: avoid bonding causing auxiliary plug/unplug under RTNL lock
RDMA is not supported in ice on a PF that has been added to a bonded interface. To enforce this, when an interface enters a bond, we unplug the auxiliary device that supports RDMA functionality. This unplug currently happens in the context of handling the netdev bonding event. This event is sent to the ice driver under RTNL context. This is causing a deadlock where the RDMA driver is waiting for the RTNL lock to complete the removal. Defer the unplugging/re-plugging of the auxiliary device to the service task so that it is not performed under the RTNL lock context. Cc: [email protected] # 6.1.x Reported-by: Jaroslav Pulchart <[email protected]> Link: https://lore.kernel.org/netdev/CAK8fFZ6A_Gphw_3-QMGKEFQk=sfCw1Qmq0TVZK3rtAi7vb621A@mail.gmail.com/ Fixes: 5cb1ebd ("ice: Fix race condition during interface enslave") Fixes: 4eace75 ("RDMA/irdma: Report the correct link speed") Signed-off-by: Dave Ertman <[email protected]> Tested-by: Arpana Arland <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 28e8cab commit 248401c

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ enum ice_pf_flags {
509509
ICE_FLAG_VF_VLAN_PRUNING,
510510
ICE_FLAG_LINK_LENIENT_MODE_ENA,
511511
ICE_FLAG_PLUG_AUX_DEV,
512+
ICE_FLAG_UNPLUG_AUX_DEV,
512513
ICE_FLAG_MTU_CHANGED,
513514
ICE_FLAG_GNSS, /* GNSS successfully initialized */
514515
ICE_PF_FLAGS_NBITS /* must be last */
@@ -955,16 +956,11 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)
955956
*/
956957
static inline void ice_clear_rdma_cap(struct ice_pf *pf)
957958
{
958-
/* We can directly unplug aux device here only if the flag bit
959-
* ICE_FLAG_PLUG_AUX_DEV is not set because ice_unplug_aux_dev()
960-
* could race with ice_plug_aux_dev() called from
961-
* ice_service_task(). In this case we only clear that bit now and
962-
* aux device will be unplugged later once ice_plug_aux_device()
963-
* called from ice_service_task() finishes (see ice_service_task()).
959+
/* defer unplug to service task to avoid RTNL lock and
960+
* clear PLUG bit so that pending plugs don't interfere
964961
*/
965-
if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
966-
ice_unplug_aux_dev(pf);
967-
962+
clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags);
963+
set_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags);
968964
clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
969965
}
970966
#endif /* _ICE_H_ */

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,18 +2316,15 @@ static void ice_service_task(struct work_struct *work)
23162316
}
23172317
}
23182318

2319-
if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) {
2320-
/* Plug aux device per request */
2321-
ice_plug_aux_dev(pf);
2319+
/* unplug aux dev per request, if an unplug request came in
2320+
* while processing a plug request, this will handle it
2321+
*/
2322+
if (test_and_clear_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags))
2323+
ice_unplug_aux_dev(pf);
23222324

2323-
/* Mark plugging as done but check whether unplug was
2324-
* requested during ice_plug_aux_dev() call
2325-
* (e.g. from ice_clear_rdma_cap()) and if so then
2326-
* plug aux device.
2327-
*/
2328-
if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
2329-
ice_unplug_aux_dev(pf);
2330-
}
2325+
/* Plug aux device per request */
2326+
if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
2327+
ice_plug_aux_dev(pf);
23312328

23322329
if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) {
23332330
struct iidc_event *event;

0 commit comments

Comments
 (0)