From: Leon Romanovsky leonro@nvidia.com
A Downstream Port with ACS Direct Translated P2P enabled routes a Request whose Address Type is Translated "to the peer Egress Port without redirection, regardless of ACS P2P Request Redirect and ACS P2P Egress Control", per PCIe r7.0 sec 6.12.3. P2PDMA assumes every Request carries an Untranslated address, so it sends an ATS client through the host bridge even where the fabric would route it straight to the peer.
Consult Direct Translated P2P for the PCI_P2PDMA_TLP_TRANSLATED classes.
Reviewed-by: Logan Gunthorpe logang@deltatee.com Tested-by: Tushar Dave tdave@nvidia.com Signed-off-by: Leon Romanovsky leonro@nvidia.com --- drivers/pci/p2pdma.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 0f9bb96f2176..ebc34aae03a1 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -546,6 +546,15 @@ pci_acs_p2pdma_request(u16 ctrl, unsigned int tlp_flags) */ if (ctrl & PCI_ACS_TB) return PCI_ACS_P2PDMA_BLOCKED; + + /* + * PCIe r7.0 sec 6.12.3: ACS Direct Translated P2P routes a + * Request carrying a Translated address to the peer "without + * redirection, regardless of ACS P2P Request Redirect and ACS + * P2P Egress Control settings". + */ + if (ctrl & PCI_ACS_DT) + return PCI_ACS_P2PDMA_DIRECT; }
return ctrl & (PCI_ACS_RR | PCI_ACS_EC) ? @@ -966,10 +975,11 @@ pci_p2pdma_map_types_unpack(unsigned long val, unsigned int tlp_flags) * redirection setting of the ports along the path. * * The client is the Requester and the provider the Completer. At the path - * divergence, check Request Redirect and Egress Control on the Requester-side - * port, and Completion Redirect for read Completions on the Completer-side - * port. Translation Blocking is checked on every port the Request passes - * instead, because it rejects a Request rather than routing it. + * divergence, check Request Redirect, Egress Control and Direct Translated + * P2P on the Requester-side port, and Completion Redirect for read + * Completions on the Completer-side port. Translation Blocking is checked on + * every port the Request passes instead, because it rejects a Request rather + * than routing it. * * Those controls apply to different TLPs, so every class named by &enum * pci_p2pdma_tlp_flags is decided from the one walk and cached together;