Skip to content

[WIP][DNM] UCT/IB/MLX5: wqe parser for uct flush - #11844

Open
jeynmann wants to merge 5 commits into
openucx:masterfrom
jeynmann:failover_uct_rcx_flush
Open

[WIP][DNM] UCT/IB/MLX5: wqe parser for uct flush#11844
jeynmann wants to merge 5 commits into
openucx:masterfrom
jeynmann:failover_uct_rcx_flush

Conversation

@jeynmann

Copy link
Copy Markdown
Contributor

What?
Add wqe parse support for uct flush.

Why?
FT need extract info from wqe before replay uct flush.

How?
Add parser for uct flush local/remote

@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/uct/ib/mlx5/rc/rc_mlx5_common.h Outdated
uint32_t qp_num;
} uct_rc_mlx5_mp_hash_key_t;

#define UCT_RC_MLX5_RMA_MAX_IOV(_av_size) \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocker — UCT_RC_MLX5_RMA_MAX_IOV is already defined earlier in this same header (line 138). This adds a second, whitespace-only-different definition of the identical macro. Please drop this block; the macro already exists a few lines above at line 138.

{
*skip_p = 0;

switch (uct_ib_mlx5_wqe_opcode(ctrl)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocker (likely CI failure) — the case MLX5_OPCODE_NOP:/case MLX5_OPCODE_RDMA_READ: body only returns when op is a flush; otherwise it falls through into default:. UCX builds with -Wall -Werror, and GCC's -Wimplicit-fallthrough (enabled by -Wall) will error on this implicit fall-through. The rest of the mlx5 code annotates intentional fall-through with /* Fall through */ (see rc_mlx5.inl:577,699,895). Please either add the annotation or restructure so the non-flush path returns UCS_ERR_UNSUPPORTED explicitly:

    switch (uct_ib_mlx5_wqe_opcode(ctrl)) {
    case MLX5_OPCODE_NOP:
    case MLX5_OPCODE_RDMA_READ:
        if (uct_rc_mlx5_op_info_is_flush(op)) {
            uct_rc_mlx5_op_info_fill_flush(info, op);
            return UCS_OK;
        }
        /* Fall through */
    default:
        ucs_diag("unsupported op %d", uct_ib_mlx5_wqe_opcode(ctrl));
        return UCS_ERR_UNSUPPORTED;
    }

Comment thread src/uct/ib/mlx5/rc/rc_mlx5_common.c Outdated
#include <uct/ib/rc/base/rc_iface.h>
#include <ucs/arch/bitops.h>
#include <ucs/profile/profile.h>
#include <endian.h>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor — #include <endian.h> and #include <string.h> are redundant; both are already pulled in via ib_mlx5.h (lines 42-43), included transitively through rc_mlx5.inl.

}

ucs_status_t
uct_rc_mlx5_op_info_fill(uct_ep_op_info_t *info, const uct_ib_mlx5_txwq_t *txwq,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor — uct_rc_mlx5_op_info_fill takes txwq, wqe_size, and callback_data but the body uses none of them. They appear to be reserved for future RMA-op decoding by the plugin. If they are part of a committed plugin ABI that lands later, a one-line comment noting that would help; otherwise consider dropping them until they are used.

@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/uct/ib/mlx5/ib_mlx5.c
return ctrl->opmod_idx_opcode >> 24;
}

void uct_ib_mlx5_txwq_copy_segs(const uct_ib_mlx5_txwq_t *txwq, const void *src,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uct_ib_mlx5_txwq_copy_segs has no callers in this PR. can we add it together with the code that uses it?

Comment thread src/uct/ib/mlx5/ib_mlx5.h

uint8_t uct_ib_mlx5_wqe_opcode(const struct mlx5_wqe_ctrl_seg *ctrl);

void uct_ib_mlx5_txwq_copy_segs(const uct_ib_mlx5_txwq_t *txwq, const void *src,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code / unused infrastructure: declaration of uct_ib_mlx5_txwq_copy_segs, which has no callers anywhere in the tree. Adding an unused helper + its declaration in a feature PR goes against the "keep the implementation as small as possible / remove anything unused" guidance in REVIEW.md.

}

ucs_status_t
uct_rc_mlx5_op_info_fill(uct_ep_op_info_t *info, const uct_ib_mlx5_txwq_t *txwq,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

txwq, wqe_size, and callback_data are unused here (and uct_rc_mlx5_op_callback_data_t is only ever passed as this unused arg). can we drop them until the path that needs them lands, to keep this PR scoped?

uct_rc_mlx5_op_info_fill_flush(info, op);

return UCS_OK;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: pls add a /* fall through */ comment here — the intended path when op is not a flush is non-obvious. Note: this does not break the build, since UCX compiles with -Wall -Werror but not -Wextra, so -Wimplicit-fallthrough is not active.

while (ci != txwq->sw_pi) {
ctrl = static_cast<const struct mlx5_wqe_ctrl_seg*>(
uct_ib_mlx5_txwq_get_wqe(txwq, ci));
wqe_size = (ctrl->qpn_ds >> 24) * UCT_IB_MLX5_WQE_SEG_SIZE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: wqe_size = (ctrl->qpn_ds >> 24) * UCT_IB_MLX5_WQE_SEG_SIZE; re-derives the WQE ds count inline. The production uct_rc_mlx5_op_info_fill receives wqe_size as a parameter but ignores it, and the test computes its own. If a helper is intended for this, reusing it would avoid drift.

@svc-ucx

svc-ucx commented Aug 27, 2026

Copy link
Copy Markdown

🤖 CI Triage AgentUCX PR (Coverity coverity release on coverity_rh7) · commit f4b037d2

TL;DR: The Coverity release job failed on a single new defect — MISSING_BREAK at src/uct/ib/mlx5/rc/rc_mlx5_common.c:57, where the MLX5_OPCODE_RDMA_READ case intentionally falls through into default: when the op isn't a flush; restructure the switch so the fallthrough is explicit (add break and move the diag/return after the switch).

Full analysis

Summary: coverity release on coverity_rh7 (Azure build 133002) built successfully but cov-analyze reported 1 issue, and the gating script failed the stage with ##[error]Coverity found 1 issues.

Root cause: In uct_rc_mlx5_op_info_fill(), the case MLX5_OPCODE_NOP: case MLX5_OPCODE_RDMA_READ: block only returns UCS_OK inside if (uct_rc_mlx5_op_info_is_flush(op)). When that condition is false, control falls through into default: with no break and no fallthrough annotation. Coverity flags this as an unterminated case:

  • rc_mlx5_common.c:57 unterminated_case: The case for value "MLX5_OPCODE_RDMA_READ" is not terminated by a 'break' statement.
  • rc_mlx5_common.c:63 fallthrough: The above case falls through to this one.

This function is brand new in this PR branch (failover_uct_rcx_flush), so the defect is introduced by this PR, not pre-existing. Note the whole-build log shows the compile succeeded (-Werror with GCC 4.8 does not enable -Wimplicit-fallthrough), which is why this only surfaces in Coverity.

Implicated commit: 24425c32 "UCT/IB/MLX5: Parse Flush WQEs for outstanding purge" (Zihao Zhao), carried through [REDACTED:Hex High Entropy String] and HEAD [REDACTED:Hex High Entropy String] "UCT/IB/MLX5: cleanup"

File: src/uct/ib/mlx5/rc/rc_mlx5_common.c:55-67 (defect reported at line 57, fallthrough target line 63)

Suggested fix: Make the non-flush path exit the switch explicitly rather than falling through. E.g.:

switch (uct_ib_mlx5_wqe_opcode(ctrl)) {
case MLX5_OPCODE_NOP:
case MLX5_OPCODE_RDMA_READ:
    if (uct_rc_mlx5_op_info_is_flush(op)) {
        uct_rc_mlx5_op_info_fill_flush(info, op);
        return UCS_OK;
    }
    break;
default:
    break;
}

ucs_diag("unsupported op %d", uct_ib_mlx5_wqe_opcode(ctrl));
return UCS_ERR_UNSUPPORTED;

This is behaviour-preserving and removes the implicit fallthrough entirely (preferable to adding a /* Fall through */ comment, which Coverity's MISSING_BREAK checker does not reliably suppress). Also worth double-checking that op can't be NULL on the flush path — uct_rc_mlx5_op_info_fill_flush() dereferences op->handler unconditionally while uct_rc_mlx5_op_info_try_fill_comp() explicitly guards for op != NULL, which is an inconsistency that could produce a FORWARD_NULL finding later.

Related: PR #11844 (this build); no existing issue found for this defect.

🛡️ This comment had 1 potential secret(s) redacted (Hex High Entropy String). See request_id e84b1eee-aca9-4287-8e63-b62138e06e91 in the triage console for the audit trail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants