summaryrefslogtreecommitdiff
path: root/drivers/pci/p2pdma.c
diff options
context:
space:
mode:
authorLogan Gunthorpe <logang@deltatee.com>2021-06-10 10:06:04 -0600
committerBjorn Helgaas <bhelgaas@google.com>2021-06-10 18:01:24 -0500
commit6389d43745228de128e7b1a66eb18c0ccf43e6b4 (patch)
tree712e75d76def6ae0647b39ab7a38afb5ced3e76d /drivers/pci/p2pdma.c
parent6efb943b8616ec53a5e444193dccf1af9ad627b5 (diff)
PCI/P2PDMA: Rename upstream_bridge_distance() and rework doc
The function upstream_bridge_distance() has evolved such that its name is no longer entirely reflective of what the function does. It not only calculates the distance between two peers but also calculates how the DMA addresses for those two peers should be mapped. Rename it to calc_map_type_and_dist() and rework the documentation to better describe the two pieces of information the function returns. [bhelgaas: tweak comment wording] Link: https://lore.kernel.org/r/20210610160609.28447-2-logang@deltatee.com Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/p2pdma.c')
-rw-r--r--drivers/pci/p2pdma.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 196382630363..a860137fac89 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -354,7 +354,7 @@ static bool host_bridge_whitelist(struct pci_dev *a, struct pci_dev *b)
}
static enum pci_p2pdma_map_type
-__upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
+__calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
int *dist, bool *acs_redirects, struct seq_buf *acs_list)
{
struct pci_dev *a = provider, *b = client, *bb;
@@ -433,52 +433,55 @@ static unsigned long map_types_idx(struct pci_dev *client)
}
/*
- * Find the distance through the nearest common upstream bridge between
- * two PCI devices.
+ * Calculate the P2PDMA mapping type and distance between two PCI devices.
*
- * If the two devices are the same device then 0 will be returned.
+ * If the two devices are the same PCI function, return
+ * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0.
*
- * If there are two virtual functions of the same device behind the same
- * bridge port then 2 will be returned (one step down to the PCIe switch,
- * then one step back to the same device).
+ * If they are two functions of the same device, return
+ * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge,
+ * then one hop back down to another function of the same device).
*
- * In the case where two devices are connected to the same PCIe switch, the
- * value 4 will be returned. This corresponds to the following PCI tree:
+ * In the case where two devices are connected to the same PCIe switch,
+ * return a distance of 4. This corresponds to the following PCI tree:
*
* -+ Root Port
* \+ Switch Upstream Port
- * +-+ Switch Downstream Port
+ * +-+ Switch Downstream Port 0
* + \- Device A
- * \-+ Switch Downstream Port
+ * \-+ Switch Downstream Port 1
* \- Device B
*
- * The distance is 4 because we traverse from Device A through the downstream
- * port of the switch, to the common upstream port, back up to the second
- * downstream port and then to Device B.
+ * The distance is 4 because we traverse from Device A to Downstream Port 0
+ * to the common Switch Upstream Port, back down to Downstream Port 1 and
+ * then to Device B. The mapping type returned depends on the ACS
+ * redirection setting of the ports along the path.
*
- * Any two devices that cannot communicate using p2pdma will return
- * PCI_P2PDMA_MAP_NOT_SUPPORTED.
+ * If ACS redirect is set on any port in the path, traffic between the
+ * devices will go through the host bridge, so return
+ * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return
+ * PCI_P2PDMA_MAP_BUS_ADDR.
*
* Any two devices that have a data path that goes through the host bridge
- * will consult a whitelist. If the host bridges are on the whitelist,
- * this function will return PCI_P2PDMA_MAP_THRU_HOST_BRIDGE.
- *
- * If either bridge is not on the whitelist this function returns
+ * will consult a whitelist. If the host bridge is in the whitelist, return
+ * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of
+ * ports per above. If the device is not in the whitelist, return
* PCI_P2PDMA_MAP_NOT_SUPPORTED.
*
- * If a bridge which has any ACS redirection bits set is in the path,
- * acs_redirects will be set to true. In this case, a list of all infringing
- * bridge addresses will be populated in acs_list (assuming it's non-null)
- * for printk purposes.
+ * If any ACS redirect bits are set, then acs_redirects boolean will be set
+ * to true and their PCI device names will be appended to the acs_list
+ * seq_buf. This seq_buf is used to print a warning informing the user how
+ * to disable ACS using a command line parameter. (See
+ * calc_map_type_and_dist_warn() below)
*/
static enum pci_p2pdma_map_type
-upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
+calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
int *dist, bool *acs_redirects, struct seq_buf *acs_list)
{
enum pci_p2pdma_map_type map_type;
- map_type = __upstream_bridge_distance(provider, client, dist,
- acs_redirects, acs_list);
+ map_type = __calc_map_type_and_dist(provider, client, dist,
+ acs_redirects, acs_list);
if (map_type == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE) {
if (!cpu_supports_p2pdma() &&
@@ -494,8 +497,8 @@ upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
}
static enum pci_p2pdma_map_type
-upstream_bridge_distance_warn(struct pci_dev *provider, struct pci_dev *client,
- int *dist)
+calc_map_type_and_dist_warn(struct pci_dev *provider, struct pci_dev *client,
+ int *dist)
{
struct seq_buf acs_list;
bool acs_redirects;
@@ -505,8 +508,8 @@ upstream_bridge_distance_warn(struct pci_dev *provider, struct pci_dev *client,
if (!acs_list.buffer)
return -ENOMEM;
- ret = upstream_bridge_distance(provider, client, dist, &acs_redirects,
- &acs_list);
+ ret = calc_map_type_and_dist(provider, client, dist, &acs_redirects,
+ &acs_list);
if (acs_redirects) {
pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
pci_name(provider));
@@ -565,11 +568,11 @@ int pci_p2pdma_distance_many(struct pci_dev *provider, struct device **clients,
}
if (verbose)
- ret = upstream_bridge_distance_warn(provider,
- pci_client, &distance);
+ ret = calc_map_type_and_dist_warn(provider, pci_client,
+ &distance);
else
- ret = upstream_bridge_distance(provider, pci_client,
- &distance, NULL, NULL);
+ ret = calc_map_type_and_dist(provider, pci_client,
+ &distance, NULL, NULL);
pci_dev_put(pci_client);