aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarimAllah Ahmed <karahmed@amazon.de>2018-10-11 12:49:58 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-10-11 12:49:58 -0400
commit975bb8b4dc93364bb47fcdb58812fa6cb0accc81 (patch)
tree81e0b3d0c225d7572f9cb92990b8f6717730bb1f
parent7876320f88802b22d4e2daf7eb027dd14175a0f8 (diff)
PCI/IOV: Use VF0 cached config space size for other VFs
Cache the config space size from VF0 and use it for all other VFs instead of reading it from the config space of each VF. We assume that it will be the same across all associated VFs. This is an optimization when enabling SR-IOV on a device with many VFs. Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de> [bhelgaas: use CONFIG_PCI_IOV (not CONFIG_PCI_ATS)] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/iov.c2
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/pci/probe.c17
3 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index c5f3cd4ed766..4238b539f9d8 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -133,6 +133,8 @@ static void pci_read_vf_config_common(struct pci_dev *virtfn)
133 &physfn->sriov->subsystem_vendor); 133 &physfn->sriov->subsystem_vendor);
134 pci_read_config_word(virtfn, PCI_SUBSYSTEM_ID, 134 pci_read_config_word(virtfn, PCI_SUBSYSTEM_ID,
135 &physfn->sriov->subsystem_device); 135 &physfn->sriov->subsystem_device);
136
137 physfn->sriov->cfg_size = pci_cfg_space_size(virtfn);
136} 138}
137 139
138int pci_iov_add_virtfn(struct pci_dev *dev, int id) 140int pci_iov_add_virtfn(struct pci_dev *dev, int id)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6e0d1528d471..2f1454209257 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -285,6 +285,7 @@ struct pci_sriov {
285 u16 driver_max_VFs; /* Max num VFs driver supports */ 285 u16 driver_max_VFs; /* Max num VFs driver supports */
286 struct pci_dev *dev; /* Lowest numbered PF */ 286 struct pci_dev *dev; /* Lowest numbered PF */
287 struct pci_dev *self; /* This PF */ 287 struct pci_dev *self; /* This PF */
288 u32 cfg_size; /* VF config space size */
288 u32 class; /* VF device */ 289 u32 class; /* VF device */
289 u8 hdr_type; /* VF header type */ 290 u8 hdr_type; /* VF header type */
290 u16 subsystem_vendor; /* VF subsystem vendor */ 291 u16 subsystem_vendor; /* VF subsystem vendor */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 201f9e5ff55c..575315bb7c4c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1438,12 +1438,29 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)
1438 return PCI_CFG_SPACE_EXP_SIZE; 1438 return PCI_CFG_SPACE_EXP_SIZE;
1439} 1439}
1440 1440
1441#ifdef CONFIG_PCI_IOV
1442static bool is_vf0(struct pci_dev *dev)
1443{
1444 if (pci_iov_virtfn_devfn(dev->physfn, 0) == dev->devfn &&
1445 pci_iov_virtfn_bus(dev->physfn, 0) == dev->bus->number)
1446 return true;
1447
1448 return false;
1449}
1450#endif
1451
1441int pci_cfg_space_size(struct pci_dev *dev) 1452int pci_cfg_space_size(struct pci_dev *dev)
1442{ 1453{
1443 int pos; 1454 int pos;
1444 u32 status; 1455 u32 status;
1445 u16 class; 1456 u16 class;
1446 1457
1458#ifdef CONFIG_PCI_IOV
1459 /* Read cached value for all VFs except for VF0 */
1460 if (dev->is_virtfn && !is_vf0(dev))
1461 return dev->physfn->sriov->cfg_size;
1462#endif
1463
1447 if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG) 1464 if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG)
1448 return PCI_CFG_SPACE_SIZE; 1465 return PCI_CFG_SPACE_SIZE;
1449 1466