Commit c7108979 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
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/20220201000522.505909-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d0cfa548 6533e558
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ enum i40e_state_t {
	__I40E_VIRTCHNL_OP_PENDING,
	__I40E_RECOVERY_MODE,
	__I40E_VF_RESETS_DISABLED,	/* disable resets during i40e_remove */
	__I40E_IN_REMOVE,
	__I40E_VFS_RELEASING,
	/* This must be last as it determines the size of the BITMAP */
	__I40E_STATE_SIZE__,
+29 −2
Original line number Diff line number Diff line
@@ -5372,7 +5372,15 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
	/* There is no need to reset BW when mqprio mode is on.  */
	if (pf->flags & I40E_FLAG_TC_MQPRIO)
		return 0;
	if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {

	if (!vsi->mqprio_qopt.qopt.hw) {
		if (pf->flags & I40E_FLAG_DCB_ENABLED)
			goto skip_reset;

		if (IS_ENABLED(CONFIG_I40E_DCB) &&
		    i40e_dcb_hw_get_num_tc(&pf->hw) == 1)
			goto skip_reset;

		ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
		if (ret)
			dev_info(&pf->pdev->dev,
@@ -5380,6 +5388,8 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
				 vsi->seid);
		return ret;
	}

skip_reset:
	memset(&bw_data, 0, sizeof(bw_data));
	bw_data.tc_valid_bits = enabled_tc;
	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,
				   bool lock_acquired)
{
	int ret;

	if (test_bit(__I40E_IN_REMOVE, pf->state))
		return;
	/* Now we wait for GRST to settle out.
	 * We don't have to delete the VEBs or VSIs from the hw switch
	 * because the reset will make them disappear.
@@ -12212,6 +12225,8 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)

		vsi->req_queue_pairs = queue_count;
		i40e_prep_for_reset(pf);
		if (test_bit(__I40E_IN_REMOVE, pf->state))
			return pf->alloc_rss_size;

		pf->alloc_rss_size = new_rss_size;

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

	/* VSI shall be deleted in a moment, just return EINVAL */
	if (test_bit(__I40E_IN_REMOVE, pf->state))
		return -EINVAL;

	old_prog = xchg(&vsi->xdp_prog, prog);

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

	while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
	/* Grab __I40E_RESET_RECOVERY_PENDING and set __I40E_IN_REMOVE
	 * flags, once they are set, i40e_rebuild should not be called as
	 * i40e_prep_for_reset always returns early.
	 */
	while (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
		usleep_range(1000, 2000);
	set_bit(__I40E_IN_REMOVE, pf->state);

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

	if (test_bit(__I40E_IN_REMOVE, pf->state))
		return;

	i40e_reset_and_rebuild(pf, false, false);
}