* [PATCH for 7.5] pci: Support preferring MMCONFIG for all config space accesses
@ 2026-11-03 19:16 Josh Triplett
2026-11-03 19:23 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Josh Triplett @ 2026-11-03 19:16 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Shuah Khan, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin
Cc: linux-pci, x86, linux-doc, linux-kernel
Even when MMCONFIG is available, PCIe currently defaults to IO-based
accesses for the first 256 bytes of config space.
IO-based accesses are serialized, and can cause substantial scalability
issues when initializing a large number of devices on a system with many
CPUs. (Those often coincide, because many systems have PCIe devices per
CPU.)
Add a `pci=prefer_mmconf` option to use MMCONFIG for all config space
accesses. Also add a Kconfig option (default n) to make that the
default, allowing a boot-time opt out with `pci=no_prefer_mmconf`.
Tested on an AWS c8i.48xlarge system, with 192 CPUs, over five boots
with and five boots without.
Without:
PCI init 266ms
Boot to minimal /init 726ms
With:
PCI init 213ms (~20% faster)
Boot to minimal /init 661ms (~9% faster)
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
Resending because I realized my previous submission was during the 7.4
merge window, and as a new patch this was obviously not meant for that
merge window. I'm hoping this would be a candidate for 7.5.
.../admin-guide/kernel-parameters.txt | 5 +++
arch/x86/Kconfig | 24 +++++++++++
arch/x86/pci/common.c | 41 +++++++++++++++++--
3 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 0b3c140babd9..afb77bfc96f3 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5079,6 +5079,11 @@ Kernel parameters
disable the use of PCIE advanced error reporting.
nodomains [PCI] Disable support for multiple PCI
root domains (aka PCI segments, in ACPI-speak).
+ prefer_mmconf [X86] Prefer use of MMCONFIG even for base (<256)
+ config space accesses.
+ no_prefer_mmconf [X86] Don't prefer use of MMCONFIG for
+ base (<256) config space accesses, even if
+ CONFIG_PCI_MMCONFIG_PREFERRED=y.
nommconf [X86] Disable use of MMCONFIG for PCI
Configuration
check_enable_amd_mmconf [X86] check for and enable
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 58dce0b66179..f9ac4c1bf5cd 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2905,6 +2905,30 @@ config PCI_MMCONFIG
Say Y otherwise.
+config PCI_MMCONFIG_PREFERRED
+ bool "Prefer mmconfig for all accesses"
+ depends on PCI_MMCONFIG
+ help
+ Use memory-mapped accesses for all PCI config space accesses where
+ supported.
+
+ Historically, Linux used legacy direct accesses for the first 256
+ bytes of each device's configuration space, even if memory-mapped
+ accesses were supported. Legacy accesses are serialized across all
+ CPUs, so they can become a bottleneck on systems with many CPUs.
+ Enabling this option substantially improves the scalability of PCI
+ config space accesses.
+
+ In the unlikely case that enabling this configuration option causes
+ problems, you can switch it off with `pci=no_prefer_mmconf`.
+
+ Even if this option is disabled, it can be set at boot time with
+ `pci=prefer_mmconf`; this option just sets the default.
+
+ You should say Y unless you have a very old system that doesn't
+ support this. If you have a system that requires saying N here,
+ please report it.
+
config PCI_OLPC
def_bool y
depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 63105b29fbf5..13e547f88d75 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -26,6 +26,13 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
static int pci_bf_sort;
int pci_routeirq;
+#ifdef CONFIG_PCI_MMCONFIG
+#ifdef CONFIG_PCI_MMCONFIG_PREFERRED
+static int pci_prefer_mmconf = 1;
+#else
+static int pci_prefer_mmconf;
+#endif
+#endif /* #ifdef CONFIG_PCI_MMCONFIG */
int noioapicquirk;
#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
int noioapicreroute = 0;
@@ -40,9 +47,20 @@ const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;
int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val)
{
+ bool tried_mmconf = false;
+
+#ifdef CONFIG_PCI_MMCONFIG
+ if (pci_prefer_mmconf && raw_pci_ext_ops == &pci_mmcfg) {
+ int ret = raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
+
+ if (ret != -EINVAL)
+ return ret;
+ tried_mmconf = true;
+ }
+#endif
if (domain == 0 && reg < 256 && raw_pci_ops)
return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
- if (raw_pci_ext_ops)
+ if (!tried_mmconf && raw_pci_ext_ops)
return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
return -EINVAL;
}
@@ -50,9 +68,20 @@ int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 val)
{
+ bool tried_mmconf = false;
+
+#ifdef CONFIG_PCI_MMCONFIG
+ if (pci_prefer_mmconf && raw_pci_ext_ops == &pci_mmcfg) {
+ int ret = raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
+
+ if (ret != -EINVAL)
+ return ret;
+ tried_mmconf = true;
+ }
+#endif
if (domain == 0 && reg < 256 && raw_pci_ops)
return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
- if (raw_pci_ext_ops)
+ if (!tried_mmconf && raw_pci_ext_ops)
return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
return -EINVAL;
}
@@ -551,7 +580,13 @@ char *__init pcibios_setup(char *str)
}
#endif
#ifdef CONFIG_PCI_MMCONFIG
- else if (!strcmp(str, "nommconf")) {
+ else if (!strcmp(str, "prefer_mmconf")) {
+ pci_prefer_mmconf = 1;
+ return NULL;
+ } else if (!strcmp(str, "no_prefer_mmconf")) {
+ pci_prefer_mmconf = 0;
+ return NULL;
+ } else if (!strcmp(str, "nommconf")) {
pci_probe &= ~PCI_PROBE_MMCONF;
return NULL;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH for 7.5] pci: Support preferring MMCONFIG for all config space accesses
2026-11-03 19:16 [PATCH for 7.5] pci: Support preferring MMCONFIG for all config space accesses Josh Triplett
@ 2026-11-03 19:23 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-11-03 19:23 UTC (permalink / raw)
To: Josh Triplett; +Cc: linux-pci
> Even when MMCONFIG is available, PCIe currently defaults to IO-based
> accesses for the first 256 bytes of config space.
>
> IO-based accesses are serialized, and can cause substantial scalability
> issues when initializing a large number of devices on a system with many
> CPUs. (Those often coincide, because many systems have PCIe devices per
> CPU.)
>
> Add a `pci=prefer_mmconf` option to use MMCONFIG for all config space
> accesses. Also add a Kconfig option (default n) to make that the
> default, allowing a boot-time opt out with `pci=no_prefer_mmconf`.
>
> Tested on an AWS c8i.48xlarge system, with 192 CPUs, over five boots
> with and five boots without.
>
> Without:
> PCI init 266ms
> Boot to minimal /init 726ms
>
> With:
> PCI init 213ms (~20% faster)
> Boot to minimal /init 661ms (~9% faster)
>
> Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/e1b3a7d153da74d3c50d7c90696b2881f4c0e97d.1793727991.git.josh@joshtriplett.org?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-03 19:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 19:16 [PATCH for 7.5] pci: Support preferring MMCONFIG for all config space accesses Josh Triplett
2026-11-03 19:23 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.