diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-06-24 11:10:33 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-06-24 11:55:04 +1000 |
commit | dc6dc7d43750e4a8ee82f2e35159a0f48d6801c5 (patch) | |
tree | 1d1210bae1e59f1a3dbe3e2672e4b4da0f5bca05 | |
parent | d65a2fd7e97a4aebecee5008be291860e52219ea (diff) | |
download | pci-dc6dc7d43750e4a8ee82f2e35159a0f48d6801c5.tar.gz |
PCI: Define resource allocation policy in the host bridge
This replaces the simple "preserve_config" in struct pci_host_bridge
with a more complete enumeration representing the 4 PCI resource
allocation policies I've identified accross the various architectures
and platforms.
The default is set to "claim and reassign" which corresponds to the
standard x86 behaviour unless global PCI flags such as PCI_PROBE_ONLY
and PCI_REASSIGN_ALL_RSRC are set in which case it is adjusted
accordingly.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/arm64/kernel/pci.c | 2 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 5 | ||||
-rw-r--r-- | drivers/pci/probe.c | 11 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 2 | ||||
-rw-r--r-- | include/linux/pci.h | 40 |
5 files changed, 55 insertions, 5 deletions
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index 8615c372981d6a..e541408778bde3 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -192,7 +192,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) /* If we must preserve the resource configuration, claim now */ host = pci_find_host_bridge(bus); - if (host->preserve_config) + if (host->rsrc_policy <= pci_rsrc_claim_assign) pci_bus_claim_resources(bus); /* diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 314a187ed57281..6405a8b9e82e6d 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -925,8 +925,9 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, */ obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1, IGNORE_PCI_BOOT_CONFIG_DSM, NULL); - if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0) - host_bridge->preserve_config = 1; + if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0 && + host_bridge->rsrc_policy == pci_rsrc_claim_assign) + host_bridge->rsrc_policy = pci_rsrc_claim_assign_restricted; ACPI_FREE(obj); pci_scan_child_bus(bus); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0e8e2c186f508d..aed7c1ccfd6494 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -601,6 +601,17 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge) bridge->native_shpc_hotplug = 1; bridge->native_pme = 1; bridge->native_ltr = 1; + + /* + * Establish a default resource management policy based on global + * PCI flags + */ + if (pci_has_flag(PCI_PROBE_ONLY)) + bridge->rsrc_policy = pci_rsrc_claim_only; + else if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) + bridge->rsrc_policy = pci_rsrc_assign_only; + else + bridge->rsrc_policy = pci_rsrc_claim_assign; } struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d533102b2788f3..bf622bdadd21ed 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1690,7 +1690,7 @@ static enum enable_type pci_realloc_detect(struct pci_bus *bus, return enable_local; host = pci_find_host_bridge(bus); - if (host->preserve_config) + if (host->rsrc_policy <= pci_rsrc_claim_assign_restricted) return auto_disabled; pci_walk_bus(bus, iov_resources_unassigned, &unassigned); diff --git a/include/linux/pci.h b/include/linux/pci.h index e6c8f6f8e42fb1..6fa6df074ceebf 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -486,6 +486,42 @@ static inline int pci_channel_offline(struct pci_dev *pdev) return (pdev->error_state != pci_channel_io_normal); } +/* + * PCI resource allocation policies: + * + * We currently support 4 policies which cover the requirements of all + * existing platforms. This currently only affects memory and IO resources + * and MPS/MRSS settings. Bus number sare handled separately (for now). + */ +enum pci_rsrc_policy { + /* + * Claim existing resources setup by firmware only, do not change them + * nor assign unassigned devices. MPS/MRSS settings are unchanged. + */ + pci_rsrc_claim_only, + + /* + * Claim existing resources setup by firmware, assign unassigned ones. + * This will mightwil not reallocate resources automatically unless + * pci=realloc=on is set explicitly. + * + * MPS/MRSS settings are updated + */ + pci_rsrc_claim_assign_restricted, + + /* + * Claim existing resources setup by firmware, assign unassigned ones. + * This might also reallocate resources as needed based on the selected + * reallocation strategy if CONFIG_PCI_REALLOC_ENABLE_AUTO is set. + * + * MPS/MRSS settings are updated + */ + pci_rsrc_claim_assign, + + /* Ignore existing firmware configuration and reassign everything */ + pci_rsrc_assign_only, +}; + struct pci_host_bridge { struct device dev; struct pci_bus *bus; /* Root bus */ @@ -506,7 +542,9 @@ struct pci_host_bridge { unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */ unsigned int native_pme:1; /* OS may use PCIe PME */ unsigned int native_ltr:1; /* OS may use PCIe LTR */ - unsigned int preserve_config:1; /* Preserve FW resource setup */ + + /* Resource claim/assignment policy */ + enum pci_rsrc_policy rsrc_policy; /* Resource alignment requirements */ resource_size_t (*align_resource)(struct pci_dev *dev, |