Conversation
|
🤖 CI Triage Agent — TL;DR: The "roce on worker 0" job failed because Full analysisSummary: Root cause: SIGILL inside the process while UCM installs mmap hooks by live-patching library code. Evidence this is unrelated to the PR: the branch Side observation (not the failure, but a latent bug worth filing): earlier in the same log, Implicated commit: unknown for the crash itself (pre-existing race); the most recent related change is c77bb48, shasson5 — "UCM/BISTRO: Increase grace time to reduce patch race (#11112)". PR commit a870f66 is not implicated. File: src/ucm/bistro/bistro.c:86-97 (time-based grace window + non-atomic Suggested fix:
Related: PR #11112 ("UCM/BISTRO: Increase grace time to reduce patch race", commit c77bb48) — prior mitigation of this same race; no open issue found matching "test_hooks Illegal instruction". |
|
@shasson5 please review. |
|
🤖 CI Triage Agent — TL;DR: The build failed only on the flaky timing-sensitive Full analysisSummary: Root cause: Evidence from the log: Implicated commit: Not the PR commit. The rwlock primitive/test originates from 8bbe776 "UCS: Introduce lightweight rwlock" (Artemy Kovalyov) — the only commit touching File: Suggested fix: Treat this as an unrelated flake for PR #11805 — retrigger the Azure "Tests new on worker 0" job, and rebase the branch after PR #11809 (which increases the rwlock test's sleep to remove the CI race) is merged. Longer term, make Related: #11809 (GTEST/UCS: Increase rwlock test sleep to avoid CI races); failing build PR #11805 |
|
🤖 CI Triage Agent — TL;DR: Full analysisSummary: UCP AM test over Root cause:
Implicated commit: [REDACTED:Hex High Entropy String] (PR #11805, branch File: test/gtest/ucp/test_ucp_am.cc:893-895 (crash site); per-EP traffic-class/AH-attribute code added by PR #11805 in Suggested fix:
Related: #11805, #11618, commit e7b7c86 "UCT/IB: Use global traffic class for RoCEv2 with auto configuration (#11105)"
|
|
🤖 Starting review — findings will be posted here when done. |
| * the transport's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
The new field and mask bit have no consumer in this PR — no transport reads ep_traffic_class. The doc states this is "currently implemented by the RC transport over mlx5 devices with DEVX enabled...", but the diff and PR head contain no implementation. If the API is split from the implementation on purpose, please reword the doc so it doesn't claim it is "currently implemented" until the RC mlx5 support lands, otherwise users will set it and silently get the iface default.
| * the interface's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
The new field and mask bit have no consumer in this PR — no transport reads ep_traffic_class. The doc states this is "currently implemented by the RC transport over mlx5 devices with DEVX enabled...", but the diff and PR head contain no implementation. If the API is split from the implementation on purpose, please reword the doc so it doesn't claim it is "currently implemented" until the RC mlx5 support lands.
|
Coverage gap: No test exercises the new API contract (e.g., a UCP ep-create path that sets |
Add an optional per-endpoint traffic class, settable at connect time: - UCP: ucp_ep_params_t::traffic_class, enabled by UCP_EP_PARAM_FIELD_TRAFFIC_CLASS - UCT: uct_ep_connect_to_ep_params_t::traffic_class, enabled by UCT_EP_CONNECT_TO_EP_PARAM_FIELD_TRAFFIC_CLASS The existing traffic class configuration is interface-wide, so a process cannot use different values for different endpoints on the same device. This lets a caller tag groups of endpoints separately, so the fabric can arbitrate between their flows. The value is a full 8-bit Type of Service byte, matching the format of the existing interface-wide setting. Both fields are appended at the end of their structures, so no existing field offset changes. The setting is opt-in via field_mask; when unset the behavior is unchanged. Nothing is added to the wire protocol: the value is applied locally to the local queue pair context at connect time.
0aa266e to
db57dab
Compare
|
🤖 Starting review — findings will be posted here when done. |
|
Residual coverage note (already raised in the prior review, not blocking): there is no test exercising the new field-mask paths and no implementation reads the new bits. If this is intentionally API-only ahead of the implementation, the "Currently implemented by the RC transport..." wording in both ucp_def.h and uct_v2.h is misleading and should be deferred until the implementation lands. |
|
@ybenvidia please avoid force-pushing during code review process |
|
🤖 Starting review — findings will be posted here when done. |
| * the transport's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
Misleading "Currently implemented by the RC transport over mlx5 devices with DEVX enabled..." wording. No code reads traffic_class from the params struct, so the documentation claims a working implementation that does not exist in this PR. This wording should be deferred until the implementation lands, or the PR description should state the API-only intent.
| * the interface's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
Misleading "Currently implemented by the RC transport over mlx5 devices with DEVX enabled..." wording. No code reads traffic_class from the params struct, so the documentation claims a working implementation that does not exist in this PR. This wording should be deferred until the implementation lands, or the PR description should state the API-only intent.
|
No test exercises the new API contract — no UCP ep-create or UCT connect_to_ep path sets the new field-mask bits ( |
|
🤖 CI Triage Agent — TL;DR: This is not a code/test failure — the "commit title" codestyle gate rejected the PR because one of its commits is titled Full analysisSummary: The Azure Pipelines "Codestyle / commit title" job (build 133025) exited with code 1 during its Bash step after validating the PR's commit titles. Root cause: The commit-title linter iterates over the commits in PR #11805 and requires each title to match UCX's convention
The Bash task then failed ( Implicated commit: File: No source file is at fault. The failing step is the "commit title" Bash task of the Codestyle stage in the Azure pipeline definition under Suggested fix: Rewrite the branch history to remove the non-conforming title: Simplest option, since Related: none (searches for prior "Bad commit title" reports returned only unrelated PRs: #11838, #11796, #11480, #11218, #2724)
|
|
LGTM |
| * This setting is optional. To enable it, the corresponding @ref | ||
| * UCP_EP_PARAM_FIELD_TRAFFIC_CLASS bit in the field mask must be set. | ||
| */ | ||
| uint8_t traffic_class; |
There was a problem hiding this comment.
This API change is tricky. We are trying to expose transport specific (TL) concept into UCP and we end up calling out explicitly RC/IB/ROCE. Would it make sense to define HIGH/LOW/etc. level and underneath implement relevant mapping ?
There was a problem hiding this comment.
@shamisp You're right, and I checked with Feroz Zahid on the QoS side — he says the same thing: DSCP is not what an application should be setting. So I'll rework the UCP side.
Proposed direction:
-
UCP: an abstract priority level instead of a traffic class — a small integer with 0 = highest priority. Feroz suggests reserving ~5 bits so additional levels can be given meaning later without changing the API (in practice only "high vs the rest" is used today, but this keeps the door open).
-
UCT: keep traffic_class as it is in this PR, since you said this layer is the right place for it.
-
The level-to-value mapping must be site-configurable, not hardcoded.
One design question before I code it: should UCP resolve the level into a traffic class — with the transport publishing its mapping through the iface attributes — or should the level be passed down to UCT and resolved there? The first keeps the UCT API exactly as you approved it; the second puts the mapping where the fabric config already lives.
Also @shasson5 what do you think ?
There was a problem hiding this comment.
You have two options in general:
- UCT exposing API that let's you query support levels and UCP doing the mapping
- Push this all the way down to UCT and UCT would do the level to value translation.
If we anticipate protocols orchestrating various priorities, I think (1) is correct path. If protocols are not expected to operate on QoS level, then (2) better choice.
There was a problem hiding this comment.
in our case protocols are not expected to deal with QoS (no special lanes/transport/protocols selection), so option 2 is the correct approach.
also I think maybe worth moving the new UCT level field to UCT EP creation API (uct_ep_params_t).
@shamisp WDYT?
There was a problem hiding this comment.
I think also option 2 it's the correct approach
There was a problem hiding this comment.
Move it to Ep creation instead of EP connect ? probably. Can single EP support multiple QoS levels ? This is a scalability question. Creating extra UCT EP and management those is not free.
There was a problem hiding this comment.
@ybenvidia do you have a requirement/design document that describes the specific use case/scenario that we need to support?
| * UCT_EP_CONNECT_TO_EP_PARAM_FIELD_TRAFFIC_CLASS bit in the field mask | ||
| * must be set. | ||
| */ | ||
| uint8_t traffic_class; |
There was a problem hiding this comment.
On UCT this makes much more sense but for UCP as I mentioned earlier it is not a good abstraction.
What
Add an optional per-endpoint traffic class to the UCP and UCT (v2) APIs:
ucp_ep_params_t::ep_traffic_class, enabled byUCP_EP_PARAM_FIELD_EP_TRAFFIC_CLASSuct_ep_connect_to_ep_params_t::ep_traffic_class, enabled byUCT_EP_CONNECT_TO_EP_PARAM_FIELD_EP_TRAFFIC_CLASSThis PR contains only the API definitions. The implementation follows in a
separate PR (see "Follow-up" below).
Why this cannot be done with the existing configuration
UCX already supports a traffic class, but only as an interface-wide
setting (
UCX_IB_TRAFFIC_CLASS), programmed into every QP created on thatinterface. It is a single value per process/interface.
The use case requires several different values simultaneously within the same
process and the same interface: endpoints belonging to different logical
groups must be tagged differently so the fabric can arbitrate between their
flows.
Concretely, for collective-communication QoS: a UCC team (≈ an MPI
communicator) is created with a priority, and every UCX endpoint opened for
that team must carry the corresponding traffic class, while endpoints of other
teams — on the same worker and the same device — keep a different one. A
higher-priority collective is then simply run on a higher-priority team.
This is a per-connection property, known only by the caller at connect
time. It cannot be derived from any existing parameter, and an environment
variable cannot express it, since one process needs multiple distinct values at
the same time. Hence the API addition.
The value is deliberately kept opaque and fabric-interpreted, matching what UCX
already does with the interface-wide setting: on RoCEv2 it ends up as the IP
DSCP code point, on IB as the GRH traffic class. No new semantics are
introduced — the same field UCX already programs simply becomes settable per
endpoint. Actual arbitration must still be configured on the fabric
(PFC/ETS/DSCP-to-priority mapping); UCX only carries the value.
Backward compatibility
Wire compatibility — unchanged. Nothing is added to the wire protocol. The
traffic class is not packed into UCX addresses and not exchanged in wireup
messages; it is applied locally, by each side, to its own QP context at connect
time. An old peer and a new peer interoperate with a bit-identical wire format.
Each side applies its own value to its own QP, with no negotiation. If only one
side sets it, that side's outgoing packets carry its traffic class and the peer
keeps the existing default — a partial QoS effect, but no protocol breakage.
This mirrors the existing behavior of the interface-wide setting.
ABI compatibility — preserved. Both new fields are appended at the end
of their respective structures, so no existing field offset changes.
Behavioral compatibility — none by default. The feature is strictly opt-in
through
field_mask. When the bit is not set, the code path is unchanged andfalls back to the existing interface-wide value, so current applications are
bit-for-bit unaffected.
Follow-up
Implementation PR: #11618 (UCP endpoint plumbing + RC mlx5 DEVX QP
programming), rebased on top of this one once merged.