Skip to content

Commit 7ae42ef

Browse files
SlawomirLabaanguy11
authored andcommitted
iavf: Fix iavf_shutdown to call iavf_remove instead iavf_close
Make the flow for pci shutdown be the same to the pci remove. iavf_shutdown was implementing an incomplete version of iavf_remove. It misses several calls to the kernel like iavf_free_misc_irq, iavf_reset_interrupt_capability, iounmap that might break the system on reboot or hibernation. Implement the call of iavf_remove directly in iavf_shutdown to close this gap. Fixes below error messages (dmesg) during shutdown stress tests - [685814.900917] ice 0000:88:00.0: MAC 02:d0:5f:82:43:5d does not exist for VF 0 [685814.900928] ice 0000:88:00.0: MAC 33:33:00:00:00:01 does not exist for VF 0 Reproduction: 1. Create one VF interface: echo 1 > /sys/class/net/<interface_name>/device/sriov_numvfs 2. Run live dmesg on the host: dmesg -wH 3. On SUT, script below steps into vf_namespace_assignment.sh <#!/bin/sh> // Remove <>. Git removes # line if=<VF name> (edit this per VF name) loop=0 while true; do echo test round $loop let loop++ ip netns add ns$loop ip link set dev $if up ip link set dev $if netns ns$loop ip netns exec ns$loop ip link set dev $if up ip netns exec ns$loop ip link set dev $if netns 1 ip netns delete ns$loop done 4. Run the script for at least 1000 iterations on SUT: ./vf_namespace_assignment.sh Expected result: No errors in dmesg. Fixes: 129cf89 ("iavf: rename functions and structs to new name") Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com> Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Reviewed-by: Ahmed Zaki <ahmed.zaki@intel.com> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Co-developed-by: Ranganatha Rao <ranganatha.rao@intel.com> Signed-off-by: Ranganatha Rao <ranganatha.rao@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent 09d23b8 commit 7ae42ef

1 file changed

Lines changed: 21 additions & 51 deletions

File tree

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -276,27 +276,6 @@ void iavf_free_virt_mem(struct iavf_hw *hw, struct iavf_virt_mem *mem)
276276
kfree(mem->va);
277277
}
278278

279-
/**
280-
* iavf_lock_timeout - try to lock mutex but give up after timeout
281-
* @lock: mutex that should be locked
282-
* @msecs: timeout in msecs
283-
*
284-
* Returns 0 on success, negative on failure
285-
**/
286-
static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
287-
{
288-
unsigned int wait, delay = 10;
289-
290-
for (wait = 0; wait < msecs; wait += delay) {
291-
if (mutex_trylock(lock))
292-
return 0;
293-
294-
msleep(delay);
295-
}
296-
297-
return -1;
298-
}
299-
300279
/**
301280
* iavf_schedule_reset - Set the flags and schedule a reset event
302281
* @adapter: board private structure
@@ -4914,34 +4893,6 @@ int iavf_process_config(struct iavf_adapter *adapter)
49144893
return 0;
49154894
}
49164895

4917-
/**
4918-
* iavf_shutdown - Shutdown the device in preparation for a reboot
4919-
* @pdev: pci device structure
4920-
**/
4921-
static void iavf_shutdown(struct pci_dev *pdev)
4922-
{
4923-
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
4924-
struct net_device *netdev = adapter->netdev;
4925-
4926-
netif_device_detach(netdev);
4927-
4928-
if (netif_running(netdev))
4929-
iavf_close(netdev);
4930-
4931-
if (iavf_lock_timeout(&adapter->crit_lock, 5000))
4932-
dev_warn(&adapter->pdev->dev, "%s: failed to acquire crit_lock\n", __func__);
4933-
/* Prevent the watchdog from running. */
4934-
iavf_change_state(adapter, __IAVF_REMOVE);
4935-
adapter->aq_required = 0;
4936-
mutex_unlock(&adapter->crit_lock);
4937-
4938-
#ifdef CONFIG_PM
4939-
pci_save_state(pdev);
4940-
4941-
#endif
4942-
pci_disable_device(pdev);
4943-
}
4944-
49454896
/**
49464897
* iavf_probe - Device Initialization Routine
49474898
* @pdev: PCI device information struct
@@ -5152,16 +5103,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
51525103
**/
51535104
static void iavf_remove(struct pci_dev *pdev)
51545105
{
5155-
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
51565106
struct iavf_fdir_fltr *fdir, *fdirtmp;
51575107
struct iavf_vlan_filter *vlf, *vlftmp;
51585108
struct iavf_cloud_filter *cf, *cftmp;
51595109
struct iavf_adv_rss *rss, *rsstmp;
51605110
struct iavf_mac_filter *f, *ftmp;
5111+
struct iavf_adapter *adapter;
51615112
struct net_device *netdev;
51625113
struct iavf_hw *hw;
51635114

5164-
netdev = adapter->netdev;
5115+
/* Don't proceed with remove if netdev is already freed */
5116+
netdev = pci_get_drvdata(pdev);
5117+
if (!netdev)
5118+
return;
5119+
5120+
adapter = iavf_pdev_to_adapter(pdev);
51655121
hw = &adapter->hw;
51665122

51675123
if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
@@ -5273,11 +5229,25 @@ static void iavf_remove(struct pci_dev *pdev)
52735229

52745230
destroy_workqueue(adapter->wq);
52755231

5232+
pci_set_drvdata(pdev, NULL);
5233+
52765234
free_netdev(netdev);
52775235

52785236
pci_disable_device(pdev);
52795237
}
52805238

5239+
/**
5240+
* iavf_shutdown - Shutdown the device in preparation for a reboot
5241+
* @pdev: pci device structure
5242+
**/
5243+
static void iavf_shutdown(struct pci_dev *pdev)
5244+
{
5245+
iavf_remove(pdev);
5246+
5247+
if (system_state == SYSTEM_POWER_OFF)
5248+
pci_set_power_state(pdev, PCI_D3hot);
5249+
}
5250+
52815251
static SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume);
52825252

52835253
static struct pci_driver iavf_driver = {

0 commit comments

Comments
 (0)