]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0007-ice-avoid-bonding-causing-auxiliary-plug-unplug-unde.patch
replace rever of RDMA link-speed reporting patch with fix
[pve-kernel.git] / patches / kernel / 0007-ice-avoid-bonding-causing-auxiliary-plug-unplug-unde.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Dave Ertman <david.m.ertman@intel.com>
3 Date: Fri, 10 Mar 2023 11:48:33 -0800
4 Subject: [PATCH] ice: avoid bonding causing auxiliary plug/unplug under RTNL
5 lock
6
7 RDMA is not supported in ice on a PF that has been added to a bonded
8 interface. To enforce this, when an interface enters a bond, we unplug
9 the auxiliary device that supports RDMA functionality. This unplug
10 currently happens in the context of handling the netdev bonding event.
11 This event is sent to the ice driver under RTNL context. This is causing
12 a deadlock where the RDMA driver is waiting for the RTNL lock to complete
13 the removal.
14
15 Defer the unplugging/re-plugging of the auxiliary device to the service
16 task so that it is not performed under the RTNL lock context.
17
18 Cc: stable@vger.kernel.org # 6.1.x
19 Reported-by: Jaroslav Pulchart <jaroslav.pulchart@gooddata.com>
20 Link: https://lore.kernel.org/netdev/CAK8fFZ6A_Gphw_3-QMGKEFQk=sfCw1Qmq0TVZK3rtAi7vb621A@mail.gmail.com/
21 Fixes: 5cb1ebdbc434 ("ice: Fix race condition during interface enslave")
22 Fixes: 4eace75e0853 ("RDMA/irdma: Report the correct link speed")
23 Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
24 Tested-by: Arpana Arland <arpanax.arland@intel.com> (A Contingent worker at Intel)
25 Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
26 Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
27 Link: https://lore.kernel.org/r/20230310194833.3074601-1-anthony.l.nguyen@intel.com
28 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
29 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
30 ---
31 drivers/net/ethernet/intel/ice/ice.h | 14 +++++---------
32 drivers/net/ethernet/intel/ice/ice_main.c | 19 ++++++++-----------
33 2 files changed, 13 insertions(+), 20 deletions(-)
34
35 diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
36 index 713069f809ec..3cad5e6b2ad1 100644
37 --- a/drivers/net/ethernet/intel/ice/ice.h
38 +++ b/drivers/net/ethernet/intel/ice/ice.h
39 @@ -506,6 +506,7 @@ enum ice_pf_flags {
40 ICE_FLAG_VF_VLAN_PRUNING,
41 ICE_FLAG_LINK_LENIENT_MODE_ENA,
42 ICE_FLAG_PLUG_AUX_DEV,
43 + ICE_FLAG_UNPLUG_AUX_DEV,
44 ICE_FLAG_MTU_CHANGED,
45 ICE_FLAG_GNSS, /* GNSS successfully initialized */
46 ICE_PF_FLAGS_NBITS /* must be last */
47 @@ -950,16 +951,11 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)
48 */
49 static inline void ice_clear_rdma_cap(struct ice_pf *pf)
50 {
51 - /* We can directly unplug aux device here only if the flag bit
52 - * ICE_FLAG_PLUG_AUX_DEV is not set because ice_unplug_aux_dev()
53 - * could race with ice_plug_aux_dev() called from
54 - * ice_service_task(). In this case we only clear that bit now and
55 - * aux device will be unplugged later once ice_plug_aux_device()
56 - * called from ice_service_task() finishes (see ice_service_task()).
57 + /* defer unplug to service task to avoid RTNL lock and
58 + * clear PLUG bit so that pending plugs don't interfere
59 */
60 - if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
61 - ice_unplug_aux_dev(pf);
62 -
63 + clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags);
64 + set_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags);
65 clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
66 }
67 #endif /* _ICE_H_ */
68 diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
69 index 381146282439..56155a04cc0c 100644
70 --- a/drivers/net/ethernet/intel/ice/ice_main.c
71 +++ b/drivers/net/ethernet/intel/ice/ice_main.c
72 @@ -2316,18 +2316,15 @@ static void ice_service_task(struct work_struct *work)
73 }
74 }
75
76 - if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) {
77 - /* Plug aux device per request */
78 - ice_plug_aux_dev(pf);
79 + /* unplug aux dev per request, if an unplug request came in
80 + * while processing a plug request, this will handle it
81 + */
82 + if (test_and_clear_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags))
83 + ice_unplug_aux_dev(pf);
84
85 - /* Mark plugging as done but check whether unplug was
86 - * requested during ice_plug_aux_dev() call
87 - * (e.g. from ice_clear_rdma_cap()) and if so then
88 - * plug aux device.
89 - */
90 - if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
91 - ice_unplug_aux_dev(pf);
92 - }
93 + /* Plug aux device per request */
94 + if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
95 + ice_plug_aux_dev(pf);
96
97 if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) {
98 struct iidc_event *event;