Patch "sfc: avoid double pci_remove of VFs" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    sfc: avoid double pci_remove of VFs

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     sfc-avoid-double-pci_remove-of-vfs.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 848ef9f08597b3fdc65b79625aae0206a8ca6f38
Author: �ñigo Huguet <ihuguet@xxxxxxxxxx>
Date:   Mon Jun 21 17:32:35 2021 +0200

    sfc: avoid double pci_remove of VFs
    
    [ Upstream commit 45423cff1db66cf0993e8a9bd0ac93e740149e49 ]
    
    If pci_remove was called for a PF with VFs, the removal of the VFs was
    called twice from efx_ef10_sriov_fini: one directly with pci_driver->remove
    and another implicit by calling pci_disable_sriov, which also perform
    the VFs remove. This was leading to crashing the kernel on the second
    attempt.
    
    Given that pci_disable_sriov already calls to pci remove function, get
    rid of the direct call to pci_driver->remove from the driver.
    
    2 different ways to trigger the bug:
    - Create one or more VFs, then attach the PF to a virtual machine (at
      least with qemu/KVM)
    - Create one or more VFs, then remove the PF with:
      echo 1 > /sys/bus/pci/devices/PF_PCI_ID/remove
    
    Removing sfc module does not trigger the error, at least for me, because
    it removes the VF first, and then the PF.
    
    Example of a log with the error:
        list_del corruption, ffff967fd20a8ad0->next is LIST_POISON1 (dead000000000100)
        ------------[ cut here ]------------
        kernel BUG at lib/list_debug.c:47!
        [...trimmed...]
        RIP: 0010:__list_del_entry_valid.cold.1+0x12/0x4c
        [...trimmed...]
        Call Trace:
        efx_dissociate+0x1f/0x140 [sfc]
        efx_pci_remove+0x27/0x150 [sfc]
        pci_device_remove+0x3b/0xc0
        device_release_driver_internal+0x103/0x1f0
        pci_stop_bus_device+0x69/0x90
        pci_stop_and_remove_bus_device+0xe/0x20
        pci_iov_remove_virtfn+0xba/0x120
        sriov_disable+0x2f/0xe0
        efx_ef10_pci_sriov_disable+0x52/0x80 [sfc]
        ? pcie_aer_is_native+0x12/0x40
        efx_ef10_sriov_fini+0x72/0x110 [sfc]
        efx_pci_remove+0x62/0x150 [sfc]
        pci_device_remove+0x3b/0xc0
        device_release_driver_internal+0x103/0x1f0
        unbind_store+0xf6/0x130
        kernfs_fop_write+0x116/0x190
        vfs_write+0xa5/0x1a0
        ksys_write+0x4f/0xb0
        do_syscall_64+0x5b/0x1a0
        entry_SYSCALL_64_after_hwframe+0x65/0xca
    
    Signed-off-by: �ñigo Huguet <ihuguet@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c
index 52bd43f45761..695e3508b4d8 100644
--- a/drivers/net/ethernet/sfc/ef10_sriov.c
+++ b/drivers/net/ethernet/sfc/ef10_sriov.c
@@ -440,7 +440,6 @@ int efx_ef10_sriov_init(struct efx_nic *efx)
 void efx_ef10_sriov_fini(struct efx_nic *efx)
 {
 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
-	unsigned int i;
 	int rc;
 
 	if (!nic_data->vf) {
@@ -450,14 +449,7 @@ void efx_ef10_sriov_fini(struct efx_nic *efx)
 		return;
 	}
 
-	/* Remove any VFs in the host */
-	for (i = 0; i < efx->vf_count; ++i) {
-		struct efx_nic *vf_efx = nic_data->vf[i].efx;
-
-		if (vf_efx)
-			vf_efx->pci_dev->driver->remove(vf_efx->pci_dev);
-	}
-
+	/* Disable SRIOV and remove any VFs in the host */
 	rc = efx_ef10_pci_sriov_disable(efx, true);
 	if (rc)
 		netif_dbg(efx, drv, efx->net_dev,



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux