aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2020-10-21 09:58:34 -0500
committerBjorn Helgaas <bhelgaas@google.com>2020-10-21 09:58:34 -0500
commit28a18aec59551e0f86f0983c0eec7b6470632790 (patch)
tree58a2831fa644f19b8b2c44ea93fe30a2435ea3fb /drivers/pci
parentMerge branch 'pci/aspm' (diff)
parentPCI: Add Kconfig options for MPS/MRRS strategy (diff)
downloadlinux-dev-28a18aec59551e0f86f0983c0eec7b6470632790.tar.xz
linux-dev-28a18aec59551e0f86f0983c0eec7b6470632790.zip
Merge branch 'pci/enumeration'
- Tone down message about missing optional MCFG (Jeremy Linton) - Add schedule point in pci_read_config() (Jiang Biao) - Add Ampere Altra SOC MCFG quirk (Tuan Phan) - Add Kconfig options for MPS/MRRS strategy (Jim Quinlan) * pci/enumeration: PCI: Add Kconfig options for MPS/MRRS strategy PCI/ACPI: Add Ampere Altra SOC MCFG quirk PCI: Add schedule point in pci_read_config() PCI/ACPI: Tone down missing MCFG message
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig62
-rw-r--r--drivers/pci/ecam.c10
-rw-r--r--drivers/pci/pci-sysfs.c1
-rw-r--r--drivers/pci/pci.c12
4 files changed, 85 insertions, 0 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 4bef5c2bae9f..d323b25ae27e 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -187,6 +187,68 @@ config PCI_HYPERV
The PCI device frontend driver allows the kernel to import arbitrary
PCI devices from a PCI backend to support PCI driver domains.
+choice
+ prompt "PCI Express hierarchy optimization setting"
+ default PCIE_BUS_DEFAULT
+ depends on PCI && EXPERT
+ help
+ MPS (Max Payload Size) and MRRS (Max Read Request Size) are PCIe
+ device parameters that affect performance and the ability to
+ support hotplug and peer-to-peer DMA.
+
+ The following choices set the MPS and MRRS optimization strategy
+ at compile-time. The choices are the same as those offered for
+ the kernel command-line parameter 'pci', i.e.,
+ 'pci=pcie_bus_tune_off', 'pci=pcie_bus_safe',
+ 'pci=pcie_bus_perf', and 'pci=pcie_bus_peer2peer'.
+
+ This is a compile-time setting and can be overridden by the above
+ command-line parameters. If unsure, choose PCIE_BUS_DEFAULT.
+
+config PCIE_BUS_TUNE_OFF
+ bool "Tune Off"
+ depends on PCI
+ help
+ Use the BIOS defaults; don't touch MPS at all. This is the same
+ as booting with 'pci=pcie_bus_tune_off'.
+
+config PCIE_BUS_DEFAULT
+ bool "Default"
+ depends on PCI
+ help
+ Default choice; ensure that the MPS matches upstream bridge.
+
+config PCIE_BUS_SAFE
+ bool "Safe"
+ depends on PCI
+ help
+ Use largest MPS that boot-time devices support. If you have a
+ closed system with no possibility of adding new devices, this
+ will use the largest MPS that's supported by all devices. This
+ is the same as booting with 'pci=pcie_bus_safe'.
+
+config PCIE_BUS_PERFORMANCE
+ bool "Performance"
+ depends on PCI
+ help
+ Use MPS and MRRS for best performance. Ensure that a given
+ device's MPS is no larger than its parent MPS, which allows us to
+ keep all switches/bridges to the max MPS supported by their
+ parent. This is the same as booting with 'pci=pcie_bus_perf'.
+
+config PCIE_BUS_PEER2PEER
+ bool "Peer2peer"
+ depends on PCI
+ help
+ Set MPS = 128 for all devices. MPS configuration effected by the
+ other options could cause the MPS on one root port to be
+ different than that of the MPS on another, which may cause
+ hot-added devices or peer-to-peer DMA to fail. Set MPS to the
+ smallest possible value (128B) system-wide to avoid these issues.
+ This is the same as booting with 'pci=pcie_bus_peer2peer'.
+
+endchoice
+
source "drivers/pci/hotplug/Kconfig"
source "drivers/pci/controller/Kconfig"
source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index 8f065a42fc1a..b54d32a31669 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -168,4 +168,14 @@ const struct pci_ecam_ops pci_32b_ops = {
.write = pci_generic_config_write32,
}
};
+
+/* ECAM ops for 32-bit read only (non-compliant) */
+const struct pci_ecam_ops pci_32b_read_ops = {
+ .bus_shift = 20,
+ .pci_ops = {
+ .map_bus = pci_ecam_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write,
+ }
+};
#endif
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6d78df981d41..3b9f63d3cad6 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -708,6 +708,7 @@ static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
data[off - init_off + 3] = (val >> 24) & 0xff;
off += 4;
size -= 4;
+ cond_resched();
}
if (size >= 2) {
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8b649b01aad3..f3f64016fe32 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -101,7 +101,19 @@ unsigned long pci_hotplug_mmio_pref_size = DEFAULT_HOTPLUG_MMIO_PREF_SIZE;
#define DEFAULT_HOTPLUG_BUS_SIZE 1
unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
+
+/* PCIe MPS/MRRS strategy; can be overridden by kernel command-line param */
+#ifdef CONFIG_PCIE_BUS_TUNE_OFF
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
+#elif defined CONFIG_PCIE_BUS_SAFE
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
+#elif defined CONFIG_PCIE_BUS_PERFORMANCE
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
+#elif defined CONFIG_PCIE_BUS_PEER2PEER
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PEER2PEER;
+#else
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
+#endif
/*
* The default CLS is used if arch didn't set CLS explicitly and not