Commit 5916380c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2022-11-18 (iavf)

Ivan Vecera resolves issues related to reset by adding back call to
netif_tx_stop_all_queues() and adding calls to dev_close() to ensure
device is properly closed during reset.

Stefan Assmann removes waiting for setting of MAC address as this breaks
ARP.

Slawomir adds setting of __IAVF_IN_REMOVE_TASK bit to prevent deadlock
between remove and shutdown.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  iavf: Fix race condition between iavf_shutdown and iavf_remove
  iavf: remove INITIAL_MAC_SET to allow gARP to work properly
  iavf: Do not restart Tx queues after reset task failure
  iavf: Fix a crash during reset task
====================

Link: https://lore.kernel.org/r/20221118222439.1565245-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3349c272 a8417330
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -298,7 +298,6 @@ struct iavf_adapter {
#define IAVF_FLAG_QUEUES_DISABLED		BIT(17)
#define IAVF_FLAG_SETUP_NETDEV_FEATURES		BIT(18)
#define IAVF_FLAG_REINIT_MSIX_NEEDED		BIT(20)
#define IAVF_FLAG_INITIAL_MAC_SET		BIT(23)
/* duplicates for common code */
#define IAVF_FLAG_DCB_ENABLED			0
	/* flags for admin queue service task */
+23 −18
Original line number Diff line number Diff line
@@ -1087,12 +1087,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
	if (ret)
		return ret;

	/* If this is an initial set MAC during VF spawn do not wait */
	if (adapter->flags & IAVF_FLAG_INITIAL_MAC_SET) {
		adapter->flags &= ~IAVF_FLAG_INITIAL_MAC_SET;
		return 0;
	}

	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
					       iavf_is_mac_set_handled(netdev, addr->sa_data),
					       msecs_to_jiffies(2500));
@@ -2605,8 +2599,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
		ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
	}

	adapter->flags |= IAVF_FLAG_INITIAL_MAC_SET;

	adapter->tx_desc_count = IAVF_DEFAULT_TXD;
	adapter->rx_desc_count = IAVF_DEFAULT_RXD;
	err = iavf_init_interrupt_scheme(adapter);
@@ -2921,7 +2913,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
	iavf_free_queues(adapter);
	memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
	iavf_shutdown_adminq(&adapter->hw);
	adapter->netdev->flags &= ~IFF_UP;
	adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
	iavf_change_state(adapter, __IAVF_DOWN);
	wake_up(&adapter->down_waitqueue);
@@ -3021,6 +3012,11 @@ static void iavf_reset_task(struct work_struct *work)
		iavf_disable_vf(adapter);
		mutex_unlock(&adapter->client_lock);
		mutex_unlock(&adapter->crit_lock);
		if (netif_running(netdev)) {
			rtnl_lock();
			dev_close(netdev);
			rtnl_unlock();
		}
		return; /* Do not attempt to reinit. It's dead, Jim. */
	}

@@ -3033,6 +3029,7 @@ static void iavf_reset_task(struct work_struct *work)

	if (running) {
		netif_carrier_off(netdev);
		netif_tx_stop_all_queues(netdev);
		adapter->link_up = false;
		iavf_napi_disable_all(adapter);
	}
@@ -3172,6 +3169,16 @@ static void iavf_reset_task(struct work_struct *work)

	mutex_unlock(&adapter->client_lock);
	mutex_unlock(&adapter->crit_lock);

	if (netif_running(netdev)) {
		/* Close device to ensure that Tx queues will not be started
		 * during netif_device_attach() at the end of the reset task.
		 */
		rtnl_lock();
		dev_close(netdev);
		rtnl_unlock();
	}

	dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
reset_finish:
	rtnl_lock();
@@ -5035,23 +5042,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
static void iavf_remove(struct pci_dev *pdev)
{
	struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
	struct net_device *netdev = adapter->netdev;
	struct iavf_fdir_fltr *fdir, *fdirtmp;
	struct iavf_vlan_filter *vlf, *vlftmp;
	struct iavf_cloud_filter *cf, *cftmp;
	struct iavf_adv_rss *rss, *rsstmp;
	struct iavf_mac_filter *f, *ftmp;
	struct iavf_cloud_filter *cf, *cftmp;
	struct iavf_hw *hw = &adapter->hw;
	struct net_device *netdev;
	struct iavf_hw *hw;
	int err;

	/* When reboot/shutdown is in progress no need to do anything
	 * as the adapter is already REMOVE state that was set during
	 * iavf_shutdown() callback.
	 */
	if (adapter->state == __IAVF_REMOVE)
	netdev = adapter->netdev;
	hw = &adapter->hw;

	if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
		return;

	set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
	/* Wait until port initialization is complete.
	 * There are flows where register/unregister netdev may race.
	 */