Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6bfaeb5 authored by Logan Gunthorpe's avatar Logan Gunthorpe Committed by Bjorn Helgaas
Browse files

PCI/P2PDMA: Factor out __upstream_bridge_distance()

This is a prep patch to create a second level helper. There are no
functional changes.

The root complex whitelist code will be moved into this function in a
subsequent patch.

Link: https://lore.kernel.org/r/20190730163545.4915-5-logang@deltatee.com
Link: https://lore.kernel.org/r/20190812173048.9186-5-logang@deltatee.com


Signed-off-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 72583084
Loading
Loading
Loading
Loading
+48 −40
Original line number Diff line number Diff line
@@ -296,47 +296,8 @@ static bool root_complex_whitelist(struct pci_dev *dev)
	return false;
}

/*
 * Find the distance through the nearest common upstream bridge between
 * two PCI devices.
 *
 * If the two devices are the same device then 0 will be returned.
 *
 * 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).
 *
 * 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:
 *
 *     -+  Root Port
 *      \+ Switch Upstream Port
 *       +-+ Switch Downstream Port
 *       + \- Device A
 *       \-+ Switch Downstream Port
 *         \- 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.
 *
 * Any two devices that cannot communicate using p2pdma will return
 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
 *
 * 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
 * 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.
 */
static enum pci_p2pdma_map_type
upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
__upstream_bridge_distance(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;
@@ -416,6 +377,53 @@ upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
	return PCI_P2PDMA_MAP_BUS_ADDR;
}

/*
 * Find the distance through the nearest common upstream bridge between
 * two PCI devices.
 *
 * If the two devices are the same device then 0 will be returned.
 *
 * 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).
 *
 * 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:
 *
 *     -+  Root Port
 *      \+ Switch Upstream Port
 *       +-+ Switch Downstream Port
 *       + \- Device A
 *       \-+ Switch Downstream Port
 *         \- 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.
 *
 * Any two devices that cannot communicate using p2pdma will return
 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
 *
 * 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
 * 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.
 */
static enum pci_p2pdma_map_type
upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
		int *dist, bool *acs_redirects, struct seq_buf *acs_list)
{
	return __upstream_bridge_distance(provider, client, dist,
					  acs_redirects, acs_list);
}

static enum pci_p2pdma_map_type
upstream_bridge_distance_warn(struct pci_dev *provider, struct pci_dev *client,
			      int *dist)