ixgbe: Change how we check for pre-existing and assigned VFs
authorAlexander Duyck <alexander.h.duyck@intel.com>
Wed, 23 May 2012 02:58:40 +0000 (02:58 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 21 Jul 2012 23:02:56 +0000 (16:02 -0700)
This patch does two things.  First it drops the unnecessary work of
searching for enabled VFs when we first bring up the adapter and instead
just uses pci_num_vf to determine how many VFs are enabled on the adapter.

The second thing it does is drop the use of vfdev from the vf_data_storage
structure.  Instead we just search the entire system for a VF that has us
as it's PF, and then if that VF is assigned we indicate that the VFs are
assigned.  This allows us to still check for assigned VFs even if the
vfinfo allocation has failed, or vfinfo has been freed.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h

index 5a286adc65c0241518d39d2a80c4a9cf0670654f..eb592822867060c30b8399debcc68e7e11a3192a 100644 (file)
@@ -130,7 +130,6 @@ struct vf_data_storage {
        u16 tx_rate;
        u16 vlan_count;
        u8 spoofchk_enabled;
-       struct pci_dev *vfdev;
 };
 
 struct vf_macvlans {
index 24f2b455a23f2caebebeadc5d3569f84f0099e05..9c42679ad83ed82ae17641982b519475ee55bd46 100644 (file)
@@ -7452,13 +7452,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        if (netdev->reg_state == NETREG_REGISTERED)
                unregister_netdev(netdev);
 
-       if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
-               if (!(ixgbe_check_vf_assignment(adapter)))
-                       ixgbe_disable_sriov(adapter);
-               else
-                       e_dev_warn("Unloading driver while VFs are assigned "
-                                  "- VFs will not be deallocated\n");
-       }
+       ixgbe_disable_sriov(adapter);
 
        ixgbe_clear_interrupt_scheme(adapter);
 
index 593fdd54f9ab41eac6bf7ca6036621fa03af5fc3..47b2ce740ec140fe665251851eb3aa9253f069d0 100644 (file)
 #include "ixgbe_sriov.h"
 
 #ifdef CONFIG_PCI_IOV
-static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       struct pci_dev *pvfdev;
-       u16 vf_devfn = 0;
-       int device_id;
-       int vfs_found = 0;
-
-       switch (adapter->hw.mac.type) {
-       case ixgbe_mac_82599EB:
-               device_id = IXGBE_DEV_ID_82599_VF;
-               break;
-       case ixgbe_mac_X540:
-               device_id = IXGBE_DEV_ID_X540_VF;
-               break;
-       default:
-               device_id = 0;
-               break;
-       }
-
-       vf_devfn = pdev->devfn + 0x80;
-       pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
-       while (pvfdev) {
-               if (pvfdev->devfn == vf_devfn &&
-                   (pvfdev->bus->number >= pdev->bus->number))
-                       vfs_found++;
-               vf_devfn += 2;
-               pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
-                                       device_id, pvfdev);
-       }
-
-       return vfs_found;
-}
-
 void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
                         const struct ixgbe_info *ii)
 {
@@ -86,7 +52,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
        struct vf_macvlans *mv_list;
        int pre_existing_vfs = 0;
 
-       pre_existing_vfs = ixgbe_find_enabled_vfs(adapter);
+       pre_existing_vfs = pci_num_vf(adapter->pdev);
        if (!pre_existing_vfs && !adapter->num_vfs)
                return;
 
@@ -205,14 +171,46 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
              "SRIOV disabled\n");
        ixgbe_disable_sriov(adapter);
 }
-#endif /* #ifdef CONFIG_PCI_IOV */
 
+static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct pci_dev *vfdev;
+       int dev_id;
+
+       switch (adapter->hw.mac.type) {
+       case ixgbe_mac_82599EB:
+               dev_id = IXGBE_DEV_ID_82599_VF;
+               break;
+       case ixgbe_mac_X540:
+               dev_id = IXGBE_DEV_ID_X540_VF;
+               break;
+       default:
+               return false;
+       }
+
+       /* loop through all the VFs to see if we own any that are assigned */
+       vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
+       while (vfdev) {
+               /* if we don't own it we don't care */
+               if (vfdev->is_virtfn && vfdev->physfn == pdev) {
+                       /* if it is assigned we cannot release it */
+                       if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
+                               return true;
+               }
+
+               vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev);
+       }
+
+       return false;
+}
+
+#endif /* #ifdef CONFIG_PCI_IOV */
 void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        u32 gpie;
        u32 vmdctl;
-       int i;
 
        /* set num VFs to 0 to prevent access to vfinfo */
        adapter->num_vfs = 0;
@@ -230,6 +228,15 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
                return;
 
 #ifdef CONFIG_PCI_IOV
+       /*
+        * If our VFs are assigned we cannot shut down SR-IOV
+        * without causing issues, so just leave the hardware
+        * available but disabled
+        */
+       if (ixgbe_vfs_are_assigned(adapter)) {
+               e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
+               return;
+
        /* disable iov and allow time for transactions to clear */
        pci_disable_sriov(adapter->pdev);
 #endif
@@ -254,12 +261,6 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
        /* take a breather then clean up driver data */
        msleep(100);
 
-       /* Release reference to VF devices */
-       for (i = 0; i < adapter->num_vfs; i++) {
-               if (adapter->vfinfo[i].vfdev)
-                       pci_dev_put(adapter->vfinfo[i].vfdev);
-       }
-
        adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
 }
 
@@ -493,28 +494,11 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
        return 0;
 }
 
-int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter)
-{
-#ifdef CONFIG_PCI_IOV
-       int i;
-       for (i = 0; i < adapter->num_vfs; i++) {
-               if (adapter->vfinfo[i].vfdev->dev_flags &
-                               PCI_DEV_FLAGS_ASSIGNED)
-                       return true;
-       }
-#endif
-       return false;
-}
-
 int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
 {
        unsigned char vf_mac_addr[6];
        struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
        unsigned int vfn = (event_mask & 0x3f);
-       struct pci_dev *pvfdev;
-       unsigned int device_id;
-       u16 thisvf_devfn = (pdev->devfn + 0x80 + (vfn << 1)) |
-                               (pdev->devfn & 1);
 
        bool enable = ((event_mask & 0x10000000U) != 0);
 
@@ -527,31 +511,6 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
                 * for it later.
                 */
                memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6);
-
-               switch (adapter->hw.mac.type) {
-               case ixgbe_mac_82599EB:
-                       device_id = IXGBE_DEV_ID_82599_VF;
-                       break;
-               case ixgbe_mac_X540:
-                       device_id = IXGBE_DEV_ID_X540_VF;
-                       break;
-               default:
-                       device_id = 0;
-                       break;
-               }
-
-               pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
-               while (pvfdev) {
-                       if (pvfdev->devfn == thisvf_devfn)
-                               break;
-                       pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
-                                               device_id, pvfdev);
-               }
-               if (pvfdev)
-                       adapter->vfinfo[vfn].vfdev = pvfdev;
-               else
-                       e_err(drv, "Couldn't find pci dev ptr for VF %4.4x\n",
-                             thisvf_devfn);
        }
 
        return 0;
index 2ab38d5fda92a16a00908053f270ee3f1a26a39d..1be1d30e4e78e15aef20d281aa9a2ca7066ca301 100644 (file)
@@ -42,7 +42,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
                            int vf, struct ifla_vf_info *ivi);
 void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
 void ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
-int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter);
 #ifdef CONFIG_PCI_IOV
 void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
                        const struct ixgbe_info *ii);