From: sashiko-bot@kernel.org
To: "Leon Romanovsky" <leon@kernel.org>
Cc: linux-pci@vger.kernel.org, dri-devel@lists.freedesktop.org,
linux-rdma@vger.kernel.org, kvm@vger.kernel.org,
media-ci@linuxtv.org
Subject: Re: [PATCH v12 05/19] PCI/P2PDMA: Evaluate ACS controls at the path divergence
Date: Tue, 03 Nov 2026 09:31:33 +0000 [thread overview]
Message-ID: <sashiko-outbox-194956@kernel.org> (raw)
In-Reply-To: <20261103-fix-p2p-acs-v4-0-v12-5-912101f93517@nvidia.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] PCI/P2PDMA: missing upstream forwarding check in calc_map_type_and_dist()
- [Medium] PCI/P2PDMA: masked redirect and read warnings in calc_map_type_and_dist()
--
commit ae19e046716c7bc5dbb292aa22e00859ce94d08e
Author: Leon Romanovsky <leon@kernel.org>
PCI/P2PDMA: Evaluate ACS controls at the path divergence
This commit updates calc_map_type_and_dist() to evaluate ACS directional
redirect controls at the path divergence rather than below it. It also
checks for internal routes between functions sharing a PCIe link, verifies
ACS Upstream Forwarding on shared downstream ports, and rejects unreadable
ACS Control registers.
> diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
> index dbab955dcbdbb..8ca0c9ba87c23 100644
> --- a/drivers/pci/p2pdma.c
> +++ b/drivers/pci/p2pdma.c
> @@ -589,6 +590,65 @@ static bool pci_acs_p2pdma_ctrl(struct pci_dev *pdev, u16 *ctrl)
[ ... ]
> +static struct pci_dev *
> +pci_acs_p2pdma_no_upstream_forwarding(struct pci_dev *common)
> +{
> + struct pci_dev *pdev;
> + u16 ctrl;
> +
> + for (pdev = common; pdev; pdev = pci_upstream_bridge(pdev)) {
> + if (!pci_acs_p2pdma_downstream_port(pdev))
> + continue;
> +
> + if (!pci_acs_p2pdma_ctrl(pdev, &ctrl))
> + return pdev;
> +
> + /*
> + * Include Root Ports here. The PCIe port type check excludes
> + * the legacy AMD southbridge quirk, which may sleep.
> + */
> + if (pci_dev_specific_acs_enabled(pdev, PCI_ACS_UF) > 0)
> + continue;
> +
> + if (!(pdev->acs_cap && pdev->acs_capabilities & ctrl & PCI_ACS_UF))
> + return pdev;
> + }
> +
> + return NULL;
> +}
[ ... ]
> @@ -865,57 +932,106 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
[ ... ]
> +check_paths_acs:
> + *dist = dist_a + dist_b;
>
> + /*
> + * ACS P2P routing controls apply where a TLP can route toward the peer
> + * or upstream. Below that divergence, its only route toward the other
> + * branch is upstream, so redirect controls do not affect the path.
> + */
> + if (a_child && b_child) {
> + if (pci_acs_p2pdma_ctrl(a_child, &ctrl))
> + state = pci_acs_p2pdma_completion(ctrl);
> + if (state != PCI_ACS_P2PDMA_DIRECT) {
> + pci_p2pdma_list_redir(&acs_list, &quirk_list, a_child);
> + if (state == PCI_ACS_P2PDMA_REDIRECT)
> + acs_redirect_cnt++;
> + else if (!acs_unreadable)
> + acs_unreadable = a_child;
> + }
>
> + state = PCI_ACS_P2PDMA_NOT_SUPPORTED;
> + if (pci_acs_p2pdma_ctrl(b_child, &ctrl))
> + state = pci_acs_p2pdma_request(ctrl);
> + if (state != PCI_ACS_P2PDMA_DIRECT) {
> + pci_p2pdma_list_redir(&acs_list, &quirk_list, b_child);
> + if (state == PCI_ACS_P2PDMA_REDIRECT)
> + acs_redirect_cnt++;
> + else if (!acs_unreadable)
> + acs_unreadable = b_child;
> + }
> + /*
> + * Two children of one Downstream or Root Port share a link.
> + * Use topology rather than slot numbers or the multifunction
> + * bit, since ARI functions and VFs need not share those.
> + */
> + if (pci_acs_p2pdma_downstream_port(a)) {
> + req_upstream =
> + pci_acs_p2pdma_no_internal_route(b_child, PCI_ACS_RR);
> + cpl_upstream =
> + pci_acs_p2pdma_no_internal_route(a_child, PCI_ACS_CR);
> + uf_blocked = pci_acs_p2pdma_no_upstream_forwarding(a);
> + }
> }
[Severity: High]
When provider and client sit behind different Switch Downstream Ports of a
PCIe Switch, their lowest common ancestor a in calc_map_type_and_dist() is
the Switch Upstream Port (PCI_EXP_TYPE_UPSTREAM), where
pci_acs_p2pdma_downstream_port(a) is false.
If b_child has PCI_ACS_RR or PCI_ACS_EC enabled, or a_child has PCI_ACS_CR
enabled, the switch redirects traffic upstream out of the Switch Upstream
Port a toward the host bridge. That redirected TLP then arrives on the
secondary interface of every shared Switch Downstream Port (in a cascaded
switch topology) and Root Port above a with its target also behind that same
secondary interface, requiring PCI_ACS_UF on those shared ports to reach the
host bridge.
Although pci_acs_p2pdma_no_upstream_forwarding() already walks up
pci_upstream_bridge() while skipping Switch Upstream Ports, calling it only
inside if (pci_acs_p2pdma_downstream_port(a)) skips checking the shared
Downstream and Root Ports above a when a is a Switch Upstream Port. Can this
cause calc_map_type_and_dist() to return PCI_P2PDMA_MAP_THRU_HOST_BRIDGE
instead of PCI_P2PDMA_MAP_NOT_SUPPORTED when an ancestor port above the
switch lacks PCI_ACS_UF or has an unreadable ACS Control register?
> + /*
> + * Below a shared upstream bridge, a path whose divergence ports do not
> + * redirect routes the request directly.
> + */
> + if (!acs_unreadable && !acs_redirect_cnt &&
> + !req_upstream && !cpl_upstream) {
> map_type = PCI_P2PDMA_MAP_BUS_ADDR;
> goto done;
> }
>
> + if (verbose) {
> + if (acs_unreadable)
> + pci_warn(client, "ACS Control is unreadable for provider %s at %s\n",
> + pci_name(provider), pci_name(acs_unreadable));
> + else if (uf_blocked)
> + pci_warn(client,
> + "cannot forward peer-to-peer DMA for provider %s upstream at %s\n",
> + pci_name(provider), pci_name(uf_blocked));
> + else if (req_upstream || cpl_upstream)
> + pci_warn(client,
> + "peer-to-peer DMA with provider %s requires the host bridge; no internal route between functions\n",
> + pci_name(provider));
> + else
> + pci_p2pdma_warn_redir(client, provider, &acs_list,
> + &quirk_list);
> + }
[Severity: Medium]
How are diagnostics handled here when sibling functions under a Downstream
Port or Root Port a DO support internal peer-to-peer routing (!req_upstream
&& !cpl_upstream), but have PCI_ACS_RR, PCI_ACS_EC, or PCI_ACS_CR enabled on
the functions themselves (acs_redirect_cnt > 0)?
In that case, disabling ACS redirect on the functions via
pci=disable_acs_redir= would allow them to use their internal route
(PCI_P2PDMA_MAP_BUS_ADDR) without traversing port a. However, because
uf_blocked = pci_acs_p2pdma_no_upstream_forwarding(a) is evaluated
unconditionally and checked before the final else branch in the verbose
block, if port a or an ancestor port does not have PCI_ACS_UF enabled,
calc_map_type_and_dist() only warns about upstream forwarding at uf_blocked
and suppresses pci_p2pdma_warn_redir().
Additionally, pci_acs_p2pdma_no_upstream_forwarding() is called before the
PCI_P2PDMA_MAP_BUS_ADDR check (reading PCI_ACS_CTRL up the hierarchy even
when the functions route directly), and when pci_acs_p2pdma_ctrl() fails on
an upstream port, it returns that port as uf_blocked rather than
acs_unreadable, logging an upstream-forwarding message instead of an
unreadable ACS Control warning. Should pci_acs_p2pdma_no_upstream_forwarding()
only be evaluated after the direct-route check, distinguish unreadable ACS
Control registers from missing PCI_ACS_UF, and still emit
pci_p2pdma_warn_redir() when programmable redirect bits blocked a valid
direct route?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103-fix-p2p-acs-v4-0-v12-0-912101f93517@nvidia.com?part=5
next prev parent reply other threads:[~2026-11-03 9:31 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 8:29 [PATCH v12 00/19] PCI/P2PDMA: Route peer-to-peer DMA by TLP class Leon Romanovsky
2026-11-03 8:29 ` [PATCH v12 01/19] PCI/P2PDMA: Honor device-specific ACS redirection Leon Romanovsky
2026-11-03 8:43 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 02/19] PCI/P2PDMA: Document the TLP attribute assumptions Leon Romanovsky
2026-11-03 8:45 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 03/19] PCI/P2PDMA: Derive routing from directional ACS controls Leon Romanovsky
2026-11-03 9:02 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 04/19] PCI: Reject unreadable ACS controls in isolation checks Leon Romanovsky
2026-11-03 9:09 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 05/19] PCI/P2PDMA: Evaluate ACS controls at the path divergence Leon Romanovsky
2026-11-03 9:31 ` sashiko-bot [this message]
2026-11-03 8:29 ` [PATCH v12 06/19] PCI/P2PDMA: Document directional ACS routing Leon Romanovsky
2026-11-03 9:39 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 07/19] PCI/P2PDMA: Collect the path's ACS controls before deciding Leon Romanovsky
2026-11-03 9:53 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 08/19] PCI/P2PDMA: Answer routing per TLP class Leon Romanovsky
2026-11-03 10:06 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 09/19] PCI/P2PDMA: Route Relaxed Ordering Completions directly Leon Romanovsky
2026-11-03 10:10 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 10/19] PCI/P2PDMA: Reject Translated Requests blocked by Translation Blocking Leon Romanovsky
2026-11-03 10:34 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 11/19] PCI/P2PDMA: Route Translated Requests under Direct Translated P2P Leon Romanovsky
2026-11-03 10:45 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 12/19] PCI/P2PDMA: Log detailed ACS routing diagnostics Leon Romanovsky
2026-11-03 11:01 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 13/19] PCI/P2PDMA: Add KUnit tests for the ACS routing decisions Leon Romanovsky
2026-11-03 11:03 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 14/19] PCI/P2PDMA: Test the ACS P2P routing walk Leon Romanovsky
2026-11-03 11:07 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 15/19] PCI: Add KUnit coverage for ACS isolation checks Leon Romanovsky
2026-11-03 11:11 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 16/19] PCI/P2PDMA: Document TLP-class routing Leon Romanovsky
2026-11-03 11:12 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 17/19] PCI/P2PDMA: Let a client declare that it selects ATS per mapping Leon Romanovsky
2026-11-03 11:15 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 18/19] PCI/P2PDMA: Evaluate the ATS path for clients with ATS enabled Leon Romanovsky
2026-11-03 11:34 ` sashiko-bot
2026-11-03 8:29 ` [PATCH v12 19/19] PCI/P2PDMA: Test the routing of " Leon Romanovsky
2026-11-03 11:37 ` sashiko-bot
2026-11-03 23:37 ` [PATCH v12 00/19] PCI/P2PDMA: Route peer-to-peer DMA by TLP class Bjorn Helgaas
2026-11-04 8:43 ` Leon Romanovsky
2026-11-04 17:14 ` Bjorn Helgaas
2026-11-04 19:52 ` Leon Romanovsky
2026-11-04 19:56 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-194956@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=media-ci@linuxtv.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.