From: Hans Zhang <18255117159@163.com>
To: lpieralisi@kernel.org, kwilczynski@kernel.org,
bhelgaas@google.com, helgaas@kernel.org, heiko@sntech.de,
mani@kernel.org, yue.wang@Amlogic.com
Cc: pali@kernel.org, neil.armstrong@linaro.org, robh@kernel.org,
jingoohan1@gmail.com, khilman@baylibre.com, jbrunet@baylibre.com,
martin.blumenstingl@googlemail.com, cassel@kernel.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-amlogic@lists.infradead.org,
linux-rockchip@lists.infradead.org,
Hans Zhang <18255117159@163.com>
Subject: [PATCH v9 1/3] PCI: Match the hierarchy's MPS to a device's MPSS as necessary
Date: Wed, 16 Sep 2026 23:39:05 +0800 [thread overview]
Message-ID: <20260916153907.60344-2-18255117159@163.com> (raw)
In-Reply-To: <20260916153907.60344-1-18255117159@163.com>
pci_configure_mps() enumerates top-down and programs each device's Maximum
Payload Size (MPS) to match its upstream bridge. When a device's MPS
Supported (MPSS) is too small to match, commit 9f0e89359775 ("PCI: Match
Root Port's MPS to endpoint's MPSS as necessary") reduces the upstream
bridge instead, but only when that bridge is a Root Port.
That covers an endpoint directly below a Root Port and nothing else. With
a Switch in between, the Switch ports have already inherited the Root
Port's larger MPS, the reduction is skipped because the upstream bridge is
a Switch Downstream Port, and pcie_set_mps() then fails with -EINVAL for
the endpoint. The endpoint is left at 128 bytes below a port programmed
for more, so any larger TLP it receives is treated as Malformed.
Multi-function devices hit the same hole from the other direction:
reducing the Root Port for a function with a small MPSS leaves the sibling
functions already programmed to the larger value.
Walk the hierarchy from the Root Port down and reduce every device that is
above the new value. Reducing only the ports between the device and the
Root Port is not sufficient, because a Switch may not fragment or
repackage TLPs: an already programmed sibling left at the larger MPS could
emit a TLP too large for its egress port.
This only affects PCIE_BUS_DEFAULT. PCIE_BUS_SAFE already converges the
hierarchy on the smallest MPSS in pcie_bus_configure_settings(), while
PCIE_BUS_TUNE_OFF and PCIE_BUS_PEER2PEER return before this point.
Fixes: 9f0e89359775 ("PCI: Match Root Port's MPS to endpoint's MPSS as necessary")
Co-developed-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/probe.c | 38 ++++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 27008e2ea5af..232bce2819f0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2200,9 +2200,28 @@ int pci_setup_device(struct pci_dev *dev)
return 0;
}
+static int pcie_reduce_mps(struct pci_dev *dev, void *data)
+{
+ int mps = *(int *)data;
+ int ret;
+
+ /* MPS is of type 'RsvdP' for VFs */
+ if (!pci_is_pcie(dev) || dev->is_virtfn)
+ return 0;
+
+ if (pcie_get_mps(dev) > mps) {
+ ret = pcie_set_mps(dev, mps);
+ if (ret)
+ dev_warn(&dev->dev, "failed to set MPS\n");
+ }
+
+ return 0;
+}
+
static void pci_configure_mps(struct pci_dev *dev)
{
struct pci_dev *bridge = pci_upstream_bridge(dev);
+ struct pci_dev *rp;
int mps, mpss, p_mps, rc;
if (!pci_is_pcie(dev))
@@ -2252,10 +2271,21 @@ static void pci_configure_mps(struct pci_dev *dev)
return;
mpss = 128 << dev->pcie_mpss;
- if (mpss < p_mps && pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) {
- pcie_set_mps(bridge, mpss);
- pci_info(dev, "Upstream bridge's Max Payload Size set to %d (was %d, max %d)\n",
- mpss, p_mps, 128 << bridge->pcie_mpss);
+ rp = pcie_find_root_port(bridge);
+ if (mpss < p_mps && rp) {
+ /*
+ * dev cannot be programmed to the MPS already in use above
+ * it, so reduce the hierarchy to what dev supports. A Switch
+ * may not repackage TLPs, so reducing only the upstream
+ * bridge is not enough: every port up to the Root Port has to
+ * come down as well, and so do the devices already programmed
+ * below that Root Port, which would otherwise be left sending
+ * TLPs too large for their egress port.
+ */
+ pcie_reduce_mps(rp, &mpss);
+ pci_walk_bus(rp->subordinate, pcie_reduce_mps, &mpss);
+ pci_info(dev, "Max Payload Size of %s hierarchy set to %d (was %d)\n",
+ pci_name(rp), mpss, p_mps);
p_mps = pcie_get_mps(bridge);
}
--
2.34.1
_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic
next prev parent reply other threads:[~2026-09-16 15:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 15:39 [PATCH v9 0/3] PCI: Configure Root Port MPS during host probing Hans Zhang
2026-09-16 15:39 ` Hans Zhang [this message]
2026-09-16 15:52 ` [PATCH v9 1/3] PCI: Match the hierarchy's MPS to a device's MPSS as necessary sashiko-bot
2026-09-16 16:00 ` Hans Zhang
2026-09-16 15:39 ` [PATCH v9 2/3] PCI: Configure Root Port MPS during host probing Hans Zhang
2026-09-16 15:51 ` sashiko-bot
2026-09-16 16:02 ` Hans Zhang
2026-09-16 15:39 ` [PATCH v9 3/3] PCI: dwc: Remove redundant MPS configuration Hans Zhang
2026-09-16 15:44 ` sashiko-bot
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=20260916153907.60344-2-18255117159@163.com \
--to=18255117159@163.com \
--cc=bhelgaas@google.com \
--cc=cassel@kernel.org \
--cc=heiko@sntech.de \
--cc=helgaas@kernel.org \
--cc=jbrunet@baylibre.com \
--cc=jingoohan1@gmail.com \
--cc=khilman@baylibre.com \
--cc=kwilczynski@kernel.org \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=lpieralisi@kernel.org \
--cc=mani@kernel.org \
--cc=martin.blumenstingl@googlemail.com \
--cc=neil.armstrong@linaro.org \
--cc=pali@kernel.org \
--cc=robh@kernel.org \
--cc=yue.wang@Amlogic.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®