Skip to content

Commit c710897

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2022-01-31 This series contains updates to i40e driver only. Jedrzej fixes a condition check which would cause an error when resetting bandwidth when DCB is active with one TC. Karen resolves a null pointer dereference that could occur when removing the driver while VSI rings are being disabled. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: i40e: Fix reset path while removing the driver i40e: Fix reset bw limit when DCB enabled with 1 TC ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents d0cfa54 + 6533e55 commit c710897

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ enum i40e_state_t {
144144
__I40E_VIRTCHNL_OP_PENDING,
145145
__I40E_RECOVERY_MODE,
146146
__I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */
147+
__I40E_IN_REMOVE,
147148
__I40E_VFS_RELEASING,
148149
/* This must be last as it determines the size of the BITMAP */
149150
__I40E_STATE_SIZE__,

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5372,14 +5372,24 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
53725372
/* There is no need to reset BW when mqprio mode is on. */
53735373
if (pf->flags & I40E_FLAG_TC_MQPRIO)
53745374
return 0;
5375-
if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
5375+
5376+
if (!vsi->mqprio_qopt.qopt.hw) {
5377+
if (pf->flags & I40E_FLAG_DCB_ENABLED)
5378+
goto skip_reset;
5379+
5380+
if (IS_ENABLED(CONFIG_I40E_DCB) &&
5381+
i40e_dcb_hw_get_num_tc(&pf->hw) == 1)
5382+
goto skip_reset;
5383+
53765384
ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
53775385
if (ret)
53785386
dev_info(&pf->pdev->dev,
53795387
"Failed to reset tx rate for vsi->seid %u\n",
53805388
vsi->seid);
53815389
return ret;
53825390
}
5391+
5392+
skip_reset:
53835393
memset(&bw_data, 0, sizeof(bw_data));
53845394
bw_data.tc_valid_bits = enabled_tc;
53855395
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
@@ -10853,6 +10863,9 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit,
1085310863
bool lock_acquired)
1085410864
{
1085510865
int ret;
10866+
10867+
if (test_bit(__I40E_IN_REMOVE, pf->state))
10868+
return;
1085610869
/* Now we wait for GRST to settle out.
1085710870
* We don't have to delete the VEBs or VSIs from the hw switch
1085810871
* because the reset will make them disappear.
@@ -12212,6 +12225,8 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
1221212225

1221312226
vsi->req_queue_pairs = queue_count;
1221412227
i40e_prep_for_reset(pf);
12228+
if (test_bit(__I40E_IN_REMOVE, pf->state))
12229+
return pf->alloc_rss_size;
1221512230

1221612231
pf->alloc_rss_size = new_rss_size;
1221712232

@@ -13038,6 +13053,10 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
1303813053
if (need_reset)
1303913054
i40e_prep_for_reset(pf);
1304013055

13056+
/* VSI shall be deleted in a moment, just return EINVAL */
13057+
if (test_bit(__I40E_IN_REMOVE, pf->state))
13058+
return -EINVAL;
13059+
1304113060
old_prog = xchg(&vsi->xdp_prog, prog);
1304213061

1304313062
if (need_reset) {
@@ -15928,8 +15947,13 @@ static void i40e_remove(struct pci_dev *pdev)
1592815947
i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
1592915948
i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
1593015949

15931-
while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
15950+
/* Grab __I40E_RESET_RECOVERY_PENDING and set __I40E_IN_REMOVE
15951+
* flags, once they are set, i40e_rebuild should not be called as
15952+
* i40e_prep_for_reset always returns early.
15953+
*/
15954+
while (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
1593215955
usleep_range(1000, 2000);
15956+
set_bit(__I40E_IN_REMOVE, pf->state);
1593315957

1593415958
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
1593515959
set_bit(__I40E_VF_RESETS_DISABLED, pf->state);
@@ -16128,6 +16152,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev)
1612816152
{
1612916153
struct i40e_pf *pf = pci_get_drvdata(pdev);
1613016154

16155+
if (test_bit(__I40E_IN_REMOVE, pf->state))
16156+
return;
16157+
1613116158
i40e_reset_and_rebuild(pf, false, false);
1613216159
}
1613316160

0 commit comments

Comments
 (0)