UCP/WIREUP: Add a token trailer and an ACK message to the lane address exchange - #11843
UCP/WIREUP: Add a token trailer and an ACK message to the lane address exchange#11843evgeny-leksikov wants to merge 4 commits into
Conversation
|
🤖 Starting review — findings will be posted here when done. |
…s exchange Append an optional trailer to the LANES_ADDR messages, holding the generation of the recovery round and a token section per direction: the TX tokens of the lanes the message provides, and the RX tokens of the lanes it answers. Both sections carry one length per lane and are empty until the lanes provide tokens, which lands in a follow-up patch together with their consumer, as does matching the generation against the tokens of an answer. Add LANES_ADDR_ACK, the third leg the exchange needs so that the peer which replies also receives the tokens derived from its own. The trailer is sent only towards peers of UCP_WIREUP_ADDR_TOKEN_MIN_DST_VERSION and above, and the ACK, which exists only to carry it, is withheld from older peers.
The token sections are parsed ahead of the packed addresses, so a malformed section must be rejected rather than shift the addresses. Feed crafted sections to the parser, including truncated ones, which the empty sections of the wire itself do not exercise.
9370791 to
a4d85e4
Compare
|
🤖 Starting review — findings will be posted here when done. |
| @@ -2459,3 +2459,58 @@ UCS_TEST_P(test_ucp_reconfig_connect_remote, put_canceled) | |||
| } | |||
There was a problem hiding this comment.
Coverage note: The gtest (test_ucp_wireup_token_section) only exercises ucp_wireup_skip_token_section in isolation. There is no end-to-end test that a v24<->v24 recovery exchange round-trips the trailer, nor a mixed-version test confirming an older peer still parses a trailer-less LANES_ADDR. The mixed-version path is the one the version gate above protects, so if practical it would be worth confirming via an existing recovery/fault-tolerance job.
|
🤖 CI Triage Agent — TL;DR: The Full analysisSummary: Root cause: In The code is functionally correct — Note the helper also has a real (though currently unreachable) hazard that reinforces the warning: the truncation check at wireup.c:1251–1255 returns Implicated commit: File: Suggested fix: Initialize the pointer at its declaration so no code path can leave it indeterminate: const ucp_wireup_msg_lanes_info_t *lanes_info = NULL;This is a one-line, zero-cost change that silences the diagnostic on every compiler without restructuring the control flow. Two recommended hardening follow-ups in the same patch:
Avoid "fixing" this by dropping Related: PR #11843 (this build). Prior work in the same series that introduced the LANES_ADDR exchange and its handlers:
|
Master bumped UCP_API_MINOR to 24. A gate of 23 would send the trailer to peers that still parse addresses immediately after lanes_info. Keep the original meaning of the LANES_ADDR lane maps in comments, and drop the claim that the trailer carries a length of its own.
|
🤖 Starting review — findings will be posted here when done. |
|
(question) Trailer presence relies on symmetric dst_version: both peers independently decide whether the token trailer is present using their own ucp_ep_config(ep)->key.dst_version (ucp_wireup_ep_supports_tokens). If the two ends hold asymmetric config views of the peer release version, the sender may add a trailer the receiver doesn't expect (or vice versa), causing the receiver to drop the message or misparse addresses. For recovery both directions are established, so dst_version should be consistent — but please confirm key.dst_version is guaranteed symmetric on both peers when LANES_ADDR messages flow. If yes, a note in the parse function would help; if not, this could silently stall recovery. No test/coverage gap for the parser itself; the runtime path (real recovery with tokens-capable peers exchanging ACKs) is exercised only by the existing recovery/fault-tolerance suites — worth confirming one of those runs with dst_version >= 24 peers so the ACK path is actually hit, since the trailer is version-gated. |
|
🤖 CI Triage Agent — TL;DR: The aarch64 java11 job failed in the "Build UCX" step, not in any Java test: Full analysisSummary: Root cause: In This is a new-code regression from the PR itself: the refactor that moved lanes-info parsing into Implicated commit: File: Suggested fix: Initialize the pointer at its declaration so the definite-assignment analysis is trivially satisfied: const ucp_wireup_msg_lanes_info_t *lanes_info = NULL;Optionally add Related: PR #11843 (#11843) — the failure is self-contained in this PR; no pre-existing issue found.
|
Older GCC with -Werror cannot prove lanes_info is set before the LANES_ADDR REQUEST/REPLY branches. Initialize it, keep the recovery generation in 32 bits, and skip wrap to the no-trailer sentinel.
|
🤖 Starting review — findings will be posted here when done. |
|
🤖 Review complete — no issues found. |
|
🤖 CI Triage Agent — TL;DR: The only failure in this GPU run is the GDA device test Full analysisSummary: Root cause: The Implicated commit: none in the PR diff — 6b7c7bf (Evgeny Leksikov, "UCP/WIREUP: Fix maybe-uninitialized lanes_info and shrink request_id") and its predecessors 06585cb / 532b94c touch only File: test/gtest/ucp/test_ucp_device.cc:712-727 ( Suggested fix:
Related: PR #11843 (the PR under test, "UCP/WIREUP: Add a token trailer and an ACK message to the lane address exchange"); no existing issue found for
|
| /* ucp_ep_recovery_progress owns FAILED-bit clearing and the retry | ||
| * cadence; do not clear or re-send inline here. */ | ||
|
|
||
| if (request_id == 0) { |
There was a problem hiding this comment.
| if (request_id == 0) { | |
| if (!ucp_wireup_ep_supports_tokens(ep)) { |
and perhaps assert(request_id != 0)
| UCS_BIT(0) | UCS_BIT(3) | UCS_BIT(5); | ||
|
|
||
| UCS_TEST_F(test_ucp_wireup_token_section, skip) { | ||
| std::vector<uint8_t> section = make_section({4, 0, 7}); |
There was a problem hiding this comment.
Minor: maybe add another case for make_section({0, 0, 0});?
Adopt the dst_version 24 tokens_info layout and skip_token_section parser, and keep FT TX collect, RX derive, and apply_rx_tokens on that handshake so extract stays compatible with the upstreamable wire protocol.
What?
Append an optional token trailer to the
LANES_ADDRwireup messages and add theLANES_ADDR_ACKmessage which closes the exchange. The trailer is framing only:its token sections are present but empty, and no token is queried or consumed yet.
Why?
Groundwork for hardware PSN fault tolerance. Purging a failed UCT lane requires the
PSN tokens of both directions, which have to travel with the lane addresses that
recovery already re-exchanges. Splitting the wire format out of the feature keeps the
protocol change reviewable on its own and lets the token query, per-lane storage and
their consumer land in a follow-up.
How?
Recovery today is a two-legged exchange over the AM lane. The endpoint which detects
a lane failure sends
LANES_ADDR_REQUEST, packing the addresses of the lanes itrebuilt in
provided_lane_map; the peer replies withLANES_ADDR_REPLY, packing theaddresses of the lanes it managed to rebuild in turn.
The trailer goes between the fixed
ucp_wireup_msg_lanes_info_t, which UCX 1.22already ships, and the packed addresses:
Each token section holds one length byte per lane followed by the tokens themselves,
so a lane which has no token costs one zero byte. The sections take their lanes from
the maps already in
lanes_inforather than from maps of their own: the TX sectionbelongs to
provided_lane_map, the lanes the message carries addresses for, and theRX section to
requested_lane_map, redefined as the lanes the message answers. Theaddresses stay last, so they need no length of their own.
Both peers decide on the trailer from the peer release version in
ucp_ep_config_key_t::dst_version, gated byUCP_WIREUP_ADDR_TOKEN_MIN_DST_VERSION,so nothing is added to the fixed header and older peers keep parsing the addresses
where they are today.
request_idcarries the recovery generation, echoed by thepeer, for the follow-up to tell answers of different rounds apart.
Why a third leg: an RX token is derived from the TX token of the remote side, so
each peer can only produce the RX tokens of the other one. The request carries the
initiator's TX tokens, and the reply carries both the responder's TX tokens and the
RX tokens it derived for the initiator. Nothing has yet delivered the RX tokens the
initiator derives from the reply, which is what
LANES_ADDR_ACKis for. It existsonly to carry the trailer, so it is withheld from peers below the minimum version.
Testing: gtest coverage of the section parser, including truncated sections which the
empty sections of the wire itself never produce, plus the fault-tolerance suite on
ConnectX-7 (
test_ucp_fault_toleranceandtest_ucp_wireup, no failures).