From: Vidya Sagar <vidyas@nvidia.com>
To: <bhelgaas@google.com>
Cc: <vsethi@nvidia.com>, <sdonthineni@nvidia.com>,
<kthota@nvidia.com>, <mmaddireddy@nvidia.com>,
<kumarahul@nvidia.com>, <sagar.tv@gmail.com>,
<linux-pci@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
Vidya Sagar <vidyas@nvidia.com>
Subject: [PATCH V3 0/5] PCI: Re-evaluate DEV3 14-Bit Tag Requester Enable on link mode changes
Date: Sat, 15 Aug 2026 01:46:16 +0530 [thread overview]
Message-ID: <20260814201621.2281245-1-vidyas@nvidia.com> (raw)
DEV3_CTL.14-Bit Tag Requester Enable is only meaningful while the link
operates in Flit Mode. In Non-Flit Mode the upper tag bits are not
transmitted on the wire, so a requester that still has it set emits
requests whose completions it can no longer match: the completer does
answer, but the completion comes back with the upper tag bits zero. The
requester therefore logs an Unexpected Completion for it and, once the
timer expires, a Completion Timeout as well. The completer side needs no
handling, since a completer only reflects the Tag field of the request it
answers and the spec accordingly defines no completer enable.
This happens today on the very first config read a Port issues after the
link below it comes back in a different mode, and there are two ways to
get there: a reset of any flavour, and a hot swap that replaces a card
whose link ran in Flit Mode with one that trains in Non-Flit Mode. Two
things are missing in the core:
- DEV3_CTL is not part of the state the core saves and restores, so its
contents are lost across a reset even for the devices that do get
saved and restored, and
- nothing re-evaluates the 14-Bit Tag Requester Enable when the link
mode changes. This matters most for the Port: it is the requester for
the config read the core issues to the device below as soon as the
link is back, but it is not itself saved and restored on these paths,
so it keeps its stale enable.
The series:
1/5 adds the DEV3_CAP.14-Bit Tag Requester Supported and
DEV3_CTL.14-Bit Tag Requester Enable definitions, both bit 2 of
their respective register.
2/5 moves __pcie_update_link_speed() out of line, which 4/5 needs. Pure
refactor.
3/5 saves DEV3_CTL and, on restore, drops 14-Bit Tag Requester Enable
from the value written to hardware when the live LNKSTA2.Flit_Mode
and DEV3_STA.Segment Captured say Flit Mode is gone. This covers the
devices reached via pci_dev_restore(). No other DEV3_CTL bit is
modified.
4/5 adds pci_bridge_refresh_14bit_tag(), which fixes the bridge itself
and then walks its subordinate bus, and calls it from
pci_bridge_wait_for_secondary_bus() (before the first downstream
config read after SBR, DPC release, AER bus reset, slot reset or a
bridge D3cold->D0 resume) and from __pcie_update_link_speed() (which
covers retrain, bwctrl and hotplug paths that never reach
pci_bridge_wait_for_secondary_bus()).
5/5 calls it from pciehp_check_link_status() as well. A surprise hot
swap resets nothing and the new card has no saved state, so the only
thing standing between the Port and a failed enumeration is a fixup
before pci_bus_check_dev() probes the card.
3/5 and 4/5 are independent of each other; each is useful on its own.
One deliberate asymmetry: the helper only ever clears the enable, it never
sets it. That matches how the core treats 10-Bit Tags, which it also never
enables on its own, and it means a Port that has been through a Non-Flit
link does not get 14-Bit Tags back when a Flit Mode card is plugged in
later. Restoring that automatically needs a policy for checking every
completer below the Port, which seems better left to a separate series.
The saved DEV3_CTL value is deliberately left untouched in 3/5 so that the
originally programmed value remains available if we do want it back.
Tested on an arm64 platform with a Root Port whose link comes back in
Non-Flit Mode after a reset. Resetting the subordinate bus from sysfs
(reset_subordinate, i.e. pci_reset_bridge() -> pci_try_reset_slot())
previously left the Root Port with 14-Bit Tag Requester Enable set, and
the first config read to the device below failed with a Completion Timeout
plus an Unexpected Completion. With this series the Root Port is fixed up
first,
pcieport 0002:80:00.0: cleared 14-Bit Tag Requester Enable: flit mode no longer active (DEV3_STA=0x00000008)
and the reset completes. Note that DEV3_STA.Segment Captured was still
set at that point while LNKSTA2.Flit_Mode had already dropped, which is
why both are consulted.
V3:
* Add patch-5 to handle hot-swap scenario
V2:
* Split the V1 monolithic patch into 4 patches
Vidya Sagar (5):
PCI: Add DEV3 14-Bit Tag Requester register definitions
PCI: Move __pcie_update_link_speed() out of line
PCI: Save and restore the Device 3 Control register
PCI: Clear stale 14-Bit Tag Requester Enable when a link leaves Flit
Mode
PCI: pciehp: Clear stale 14-Bit Tag Requester Enable on hot add
drivers/pci/hotplug/pciehp_hpc.c | 8 ++
drivers/pci/pci.c | 211 +++++++++++++++++++++++++++++++
drivers/pci/pci.h | 17 +--
drivers/pci/probe.c | 36 ++++++
include/uapi/linux/pci_regs.h | 2 +
5 files changed, 262 insertions(+), 12 deletions(-)
--
2.43.0
next reply other threads:[~2026-08-14 20:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 20:16 Vidya Sagar [this message]
2026-08-14 20:16 ` [PATCH V3 1/5] PCI: Add DEV3 14-Bit Tag Requester register definitions Vidya Sagar
2026-08-14 20:16 ` [PATCH V3 2/5] PCI: Move __pcie_update_link_speed() out of line Vidya Sagar
2026-08-14 20:16 ` [PATCH V3 3/5] PCI: Save and restore the Device 3 Control register Vidya Sagar
2026-08-15 6:53 ` Lukas Wunner
2026-08-14 20:16 ` [PATCH V3 4/5] PCI: Clear stale 14-Bit Tag Requester Enable when a link leaves Flit Mode Vidya Sagar
2026-08-15 7:20 ` Lukas Wunner
2026-08-14 20:16 ` [PATCH V3 5/5] PCI: pciehp: Clear stale 14-Bit Tag Requester Enable on hot add Vidya Sagar
2026-08-15 7:24 ` Lukas Wunner
2026-08-15 7:14 ` [PATCH V3 0/5] PCI: Re-evaluate DEV3 14-Bit Tag Requester Enable on link mode changes Lukas Wunner
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=20260814201621.2281245-1-vidyas@nvidia.com \
--to=vidyas@nvidia.com \
--cc=bhelgaas@google.com \
--cc=kthota@nvidia.com \
--cc=kumarahul@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mmaddireddy@nvidia.com \
--cc=sagar.tv@gmail.com \
--cc=sdonthineni@nvidia.com \
--cc=vsethi@nvidia.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