Repository navigation
UCT/IB/MLX5/RC: Implement put_sgl_zcopy #11677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
754dd7f
88dbcff
d8205aa
ec2c4b0
572312d
0e7195a
fca8728
685abda
276ceb3
63756a4
9128ce3
9538693
0c19cfa
e7c4d75
d05605f
1af61f3
60c8d46
cc94d61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /** | ||
| * Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2019. ALL RIGHTS RESERVED. | ||
| * Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2026. ALL RIGHTS RESERVED. | ||
| * | ||
| * See file LICENSE for terms. | ||
| */ | ||
|
|
@@ -175,6 +175,119 @@ ucs_status_t uct_rc_mlx5_base_ep_put_zcopy(uct_ep_h tl_ep, const uct_iov_t *iov, | |
| return status; | ||
| } | ||
|
|
||
| ucs_status_t | ||
| uct_rc_mlx5_base_ep_put_sgl_zcopy(uct_ep_h tl_ep, void * const *buffers, | ||
| const size_t *lengths, uct_mem_h const *memhs, | ||
| const uint64_t *remote_addrs, | ||
| uct_rkey_t const *rkeys, const size_t *counts, | ||
| const size_t *strides, size_t count, | ||
| uct_completion_t *comp) | ||
| { | ||
| UCT_RC_MLX5_BASE_EP_DECL(tl_ep, iface, ep); | ||
| uct_ib_mlx5_txwq_t *txwq = &ep->tx.wq; | ||
| size_t total = 0; | ||
| struct mlx5_wqe_ctrl_seg *ctrl = NULL; | ||
| struct mlx5_wqe_raddr_seg *raddr; | ||
| struct mlx5_wqe_data_seg *dptr; | ||
| size_t wqe_size, i; | ||
| uint8_t fm_ce_se, fence_flag; | ||
| uint16_t sn, pi, res_count; | ||
| uint64_t addr; | ||
| uct_rkey_t rkey; | ||
| void *curr; | ||
| size_t UCS_V_UNUSED max_count; | ||
|
|
||
| max_count = uct_rc_mlx5_base_put_sgl_zcopy_max_count(iface); | ||
| UCT_CHECK_PARAM(count <= max_count, | ||
| "put_sgl_zcopy count(%zu) should be limited by %zu", count, | ||
| max_count); | ||
| ucs_assert(ep->super.flags & UCT_RC_EP_FLAG_CONNECTED); | ||
| ucs_assert(count > 0); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In release the function will continue executing and underflow on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used |
||
|
|
||
| /* TODO: add strided elements support */ | ||
| if (ucs_unlikely((counts != NULL) || (strides != NULL))) { | ||
| ucs_error("put_sgl_zcopy does not support strided elements"); | ||
| return UCS_ERR_UNSUPPORTED; | ||
| } | ||
|
|
||
| if (iface->super.tx.cq_available < (int)count) { | ||
| UCS_STATS_UPDATE_COUNTER(iface->super.stats, | ||
| UCT_RC_IFACE_STAT_NO_CQE, 1); | ||
| UCS_STATS_UPDATE_COUNTER(ep->super.super.stats, | ||
| UCT_EP_STAT_NO_RES, 1); | ||
| return UCS_ERR_NO_RESOURCE; | ||
| } | ||
|
|
||
| UCT_RC_CHECK_NUM_RDMA_READ_RET(&iface->super, UCS_ERR_NO_RESOURCE); | ||
|
bosilca marked this conversation as resolved.
Resolved
|
||
| UCT_RC_CHECK_TXQP_VALUE_RET(&iface->super, &ep->super, | ||
|
ColinNV marked this conversation as resolved.
Resolved
|
||
| UCS_ERR_NO_RESOURCE, count - 1); | ||
|
|
||
| /* Validate all lengths before consuming the fence state */ | ||
| for (i = 0; i < count; i++) { | ||
| UCT_CHECK_LENGTH(lengths[i], 0, UCT_IB_MAX_MESSAGE_SIZE, | ||
| "put_sgl_zcopy"); | ||
| } | ||
|
Comment on lines
+216
to
+219
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to do this validity check before line 213, because otherwise it might return
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
|
||
| wqe_size = sizeof(*ctrl) + sizeof(*raddr) + sizeof(*dptr); | ||
| sn = txwq->sw_pi; | ||
|
|
||
| ucs_assert(!(txwq->flags & UCT_IB_MLX5_TXWQ_FLAG_FAILED)); | ||
| ucs_assert(ucs_div_round_up(wqe_size, MLX5_SEND_WQE_BB) == 1); | ||
|
|
||
| pi = sn; | ||
| curr = txwq->curr; | ||
|
|
||
| fence_flag = uct_rc_ep_fm(&iface->super, &txwq->fi, 1) ? | ||
|
ColinNV marked this conversation as resolved.
Resolved
|
||
| iface->config.put_fence_flag : 0; | ||
|
|
||
| for (i = 0; i < count; i++) { | ||
| fm_ce_se = ((i == 0) ? fence_flag : 0) | | ||
| ((i == count - 1) ? MLX5_WQE_CTRL_CQ_UPDATE : 0); | ||
| ctrl = curr; | ||
|
|
||
| uct_ib_mlx5_set_ctrl_seg(ctrl, pi, MLX5_OPCODE_RDMA_WRITE, 0, | ||
| txwq->super.qp_num, fm_ce_se, 0, wqe_size); | ||
|
|
||
| addr = remote_addrs[i]; | ||
| if (fence_flag != 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this check the return value of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. The return value of |
||
| rkey = uct_ib_resolve_atomic_rkey( | ||
| rkeys[i], ep->super.atomic_mr_offset, &addr); | ||
| } else { | ||
| rkey = uct_ib_md_direct_rkey(rkeys[i]); | ||
| } | ||
|
|
||
| raddr = uct_ib_mlx5_txwq_wrap_none(txwq, ctrl + 1); | ||
| uct_ib_mlx5_ep_set_rdma_seg(raddr, addr, rkey); | ||
|
|
||
| dptr = uct_ib_mlx5_txwq_wrap_none(txwq, raddr + 1); | ||
| uct_ib_mlx5_set_data_seg(dptr, buffers[i], lengths[i], | ||
| uct_ib_memh_get_lkey(memhs[i])); | ||
|
|
||
| curr = UCS_PTR_BYTE_OFFSET(ctrl, MLX5_SEND_WQE_BB); | ||
| curr = uct_ib_mlx5_txwq_wrap_exact(txwq, curr); | ||
| pi++; | ||
| total += lengths[i]; | ||
| } | ||
|
|
||
| res_count = pi - 1 - txwq->prev_sw_pi; | ||
| txwq->prev_sw_pi += res_count; | ||
| txwq->sw_pi = pi; | ||
| txwq->curr = curr; | ||
| txwq->sig_pi = txwq->prev_sw_pi; | ||
|
|
||
| uct_rc_txqp_posted(&ep->super.txqp, &iface->super, res_count, 1); | ||
|
bosilca marked this conversation as resolved.
Resolved
|
||
| uct_ib_mlx5_txwq_ring_doorbell(txwq, ctrl, txwq->sw_pi, 1); | ||
|
|
||
| uct_rc_txqp_add_send_comp(&iface->super, &ep->super.txqp, | ||
| uct_rc_ep_send_op_completion_handler, comp, sn, | ||
| UCT_RC_IFACE_SEND_OP_FLAG_ZCOPY, NULL, 0, total); | ||
|
|
||
| UCT_TL_EP_STAT_OP(&ep->super.super, PUT, ZCOPY, total); | ||
| uct_rc_ep_enable_flush_remote(&ep->super); | ||
|
|
||
| return UCS_INPROGRESS; | ||
| } | ||
|
|
||
| ucs_status_t | ||
| uct_rc_mlx5_base_ep_get_bcopy(uct_ep_h tl_ep, uct_unpack_callback_t unpack_cb, | ||
| void *arg, size_t length, uint64_t remote_addr, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
src/uct/ib/rc/base/rc_iface.c:590it says:so the 2 reserved spaces need to be taken into account here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. By default, the SQ length is 256 and the TX CQ length is 4096, so the SQ is normally exhausted first. However, a user can configure a smaller CQ using
UCX_RC_TX_CQ_LENand expose a corner case where an SGL requires more credits than are currently available whilecq_availableis still nonzero, causingpending_add()to return BUSY and spin without progress.However, your suggestion of hardcoding
tx_cq_len - 2would duplicate the reserved-CQ magic number. Instead, I added a shared helper as the single source of truth and a per-EP CQ reservation, similar totxqp_reservein #11361, and ran the SGL gtests to confirm the fix.