Skip to content

Commit 347b565

Browse files
eryk-rochanguy11
authored andcommitted
i40e: Fix kernel oops when i40e driver removes VF's
Fix the reason of kernel oops when i40e driver removed VFs. Added new __I40E_VFS_RELEASING state to signalize releasing process by PF, that it makes possible to exit of reset VF procedure. Without this patch, it is possible to suspend the VFs reset by releasing VFs resources procedure. Retrying the reset after the timeout works on the freed VF memory causing a kernel oops. Fixes: d43d60e ("i40e: ensure reset occurs when disabling VF") Signed-off-by: Eryk Rybak <[email protected]> Signed-off-by: Grzegorz Szczurek <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Tested-by: Konrad Jankowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 90449e9 commit 347b565

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ enum i40e_state_t {
142142
__I40E_VIRTCHNL_OP_PENDING,
143143
__I40E_RECOVERY_MODE,
144144
__I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */
145+
__I40E_VFS_RELEASING,
145146
/* This must be last as it determines the size of the BITMAP */
146147
__I40E_STATE_SIZE__,
147148
};

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
137137
**/
138138
static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
139139
{
140+
struct i40e_pf *pf = vf->pf;
140141
int i;
141142

142143
i40e_vc_notify_vf_reset(vf);
@@ -147,6 +148,11 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
147148
* ensure a reset.
148149
*/
149150
for (i = 0; i < 20; i++) {
151+
/* If PF is in VFs releasing state reset VF is impossible,
152+
* so leave it.
153+
*/
154+
if (test_bit(__I40E_VFS_RELEASING, pf->state))
155+
return;
150156
if (i40e_reset_vf(vf, false))
151157
return;
152158
usleep_range(10000, 20000);
@@ -1574,6 +1580,8 @@ void i40e_free_vfs(struct i40e_pf *pf)
15741580

15751581
if (!pf->vf)
15761582
return;
1583+
1584+
set_bit(__I40E_VFS_RELEASING, pf->state);
15771585
while (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
15781586
usleep_range(1000, 2000);
15791587

@@ -1631,6 +1639,7 @@ void i40e_free_vfs(struct i40e_pf *pf)
16311639
}
16321640
}
16331641
clear_bit(__I40E_VF_DISABLE, pf->state);
1642+
clear_bit(__I40E_VFS_RELEASING, pf->state);
16341643
}
16351644

16361645
#ifdef CONFIG_PCI_IOV

0 commit comments

Comments
 (0)