Skip to content

Commit

Permalink
ixgbe: Change how we check for pre-existing and assigned VFs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Jul 21, 2012
1 parent 99d7448 commit 9297127
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 94 deletions.
1 change: 0 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ struct vf_data_storage {
u16 tx_rate;
u16 vlan_count;
u8 spoofchk_enabled;
struct pci_dev *vfdev;
};

struct vf_macvlans {
Expand Down
8 changes: 1 addition & 7 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
129 changes: 44 additions & 85 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,40 +44,6 @@
#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)
{
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 9297127

Please sign in to comment.