aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-06-24 11:10:33 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-06-24 11:55:04 +1000
commitdc6dc7d43750e4a8ee82f2e35159a0f48d6801c5 (patch)
tree1d1210bae1e59f1a3dbe3e2672e4b4da0f5bca05
parentd65a2fd7e97a4aebecee5008be291860e52219ea (diff)
downloadpci-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.c2
-rw-r--r--drivers/acpi/pci_root.c5
-rw-r--r--drivers/pci/probe.c11
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--include/linux/pci.h40
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,