Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
bb7a13a
UCP/RNDV: Throttle rndv fragment requests (both pipeline and standalo…
amastbaum Dec 8, 2025
8d97668
UCP/RNDV: change 'ppln' prefix to 'mtype'
amastbaum Dec 15, 2025
30c5741
UCP/RNDV: prioritize PUT ops over RTR
amastbaum Dec 23, 2025
7716784
UCP/RNDV: unite RTR, PUT and GET in a generic ucp_proto_rndv_mtype_fc…
amastbaum Dec 31, 2025
3eddbac
UCP/RNDV: some fixes
amastbaum Dec 31, 2025
a9685bb
UCP/RNDV: clang
amastbaum Dec 31, 2025
31eefc1
UCP/RNDV: some fixes
amastbaum Dec 31, 2025
8275c36
UCP/RNDV: change fragments distibution across different protos
amastbaum Dec 31, 2025
2701d7f
UCP/RNDV: some changes
amastbaum Dec 31, 2025
7766da1
UCP/RNDV: Added gtest
amastbaum Dec 31, 2025
4e515c3
UCP/RNDV: pre-compute max frags
amastbaum Jan 4, 2026
50b208f
UCP/RNDV: align max frags to mpool chunk size
amastbaum Jan 4, 2026
ac696c7
UCP/RNDV: adjust gtest to MAX_MEM
amastbaum Jan 5, 2026
e97bc99
UCP/RNDV: pre-define stats-counter-array size
amastbaum Jan 7, 2026
45ef504
UCP/RNDV: code review fixes
amastbaum Mar 8, 2026
9c3bce9
UCP/RNDV: cr fixes
amastbaum Mar 16, 2026
5c67c59
UCP/RNDV: STAT_RNDV_MTYPE_FC_THROTTLED -> STAT_RNDV_MTYPE_FC_OK
amastbaum Mar 16, 2026
1239821
UCP/RNDV: remove UCP_WORKER_STAT_RNDV_MTYPE_FC_OK stats + remove fc_i…
amastbaum Mar 16, 2026
a757e00
UCP/RNDV: more fixes
amastbaum Mar 16, 2026
8c447d6
UCP/RNDV: put throttle in request_init
amastbaum Mar 16, 2026
8f5f4ca
UCP/RNDV: put decrement in mdesc_release
amastbaum Mar 16, 2026
7627bcb
UCP/RNDV: some fixes (enable by default, remove enable field)
amastbaum Mar 16, 2026
415a289
UCP/RNDV: make ratios configurable
amastbaum Mar 16, 2026
a84c684
UCP/RNDV: two pending queues instead of 3 - high prio and low prio
amastbaum Mar 17, 2026
aed4dc6
UCP/RNDV: queue indexing
amastbaum Mar 17, 2026
ea99ea1
UCP/RNDV: limit mem using mpool::max_elems - removing differentiation…
amastbaum Mar 17, 2026
5aacd1b
UCP/RNDV: clang
amastbaum Mar 17, 2026
dce0ce4
UCP/RNDV: small fixes
amastbaum Mar 17, 2026
0f877be
UCP/RNDV: disable throttling by default (RNDV_MTYPE_WORKER_MAX_MEM=inf)
amastbaum Aug 11, 2026
b548a0b
UCP/RNDV: code review fixes
amastbaum Aug 12, 2026
b802165
UCP/RNDV: code review fixes 2
amastbaum Aug 12, 2026
bc5cd27
UCP/RNDV: rename RNDV_MTYPE_WORKER_MAX_MEM to RNDV_FRAG_WORKER_MAX_MEM
amastbaum Aug 12, 2026
398d835
UCP/RNDV: throttle only in case of NO_RESOURCE
amastbaum Aug 12, 2026
e683f95
UCP/RNDV: more fixes
amastbaum Aug 12, 2026
c974c97
UCP/RNDV: add abort path gtests
amastbaum Aug 19, 2026
89505d2
UCP/RNDV: add abort path support
amastbaum Aug 19, 2026
d52d74c
UCP/RNDV: abort gtest fix
amastbaum Aug 20, 2026
4c746e9
UCP/RNDV: code review fixes
amastbaum Aug 26, 2026
9b61860
UCP/RNDV: more code review fixes + fixed mtype initialization
amastbaum Aug 27, 2026
9f30c96
UCP/RNDV: small fix
amastbaum Aug 30, 2026
231bdeb
UCP/RNDV: some code review fixes
amastbaum Sep 2, 2026
b58d48d
UCP/RNDV: code review
amastbaum Sep 7, 2026
586d57d
UCP/RNDV: Apply fragment mpool limit only to proto v2
amastbaum Sep 8, 2026
c356ccc
UCP/RNDV: Abort throttled mtype requests on EP purge
amastbaum Sep 15, 2026
af47dde
UCP/RNDV: Pass mtype FC wakeup to next waiter on abort
amastbaum Sep 16, 2026
3176441
UCP/RNDV: small fixes
amastbaum Sep 16, 2026
d78e45d
UCP/RNDV: merge master
amastbaum Sep 16, 2026
7ab5730
UCP/RNDV: Skip proto-v1 test cases
amastbaum Sep 16, 2026
e1be1df
UCP/RNDV: Replay throttled mtype requests on EP reconfiguration
amastbaum Sep 16, 2026
b3ea1ee
UCP/RNDV: Keep request size unchanged by moving mtype FC EP link
amastbaum Sep 17, 2026
65e9129
UCP/RNDV: code review fixes
amastbaum Sep 17, 2026
3096ac9
UCP/RNDV: small fixes
amastbaum Sep 17, 2026
ac56848
UCP/RNDV: CI failure - allow aborting RTS request with completed frag…
amastbaum Sep 22, 2026
2818753
UCP/RNDV: updated master
amastbaum Sep 22, 2026
c1efc3b
UCP/RNDV: small fixes
amastbaum Sep 22, 2026
b61d637
UCP/RNDV: Fix mtype FC wakeup, GET abort gate and fragment limit roun…
amastbaum Sep 23, 2026
c984f11
UCP/RNDV: Dequeue throttled requests of an endpoint in one pass
amastbaum Sep 23, 2026
26499f3
UCP/RNDV: Merge master and encode mtype FC state in one request flag
amastbaum Oct 4, 2026
5a8bdb4
UCP/RNDV: Keep part of the fragment quota in a pool for PUT/GET only
amastbaum Oct 6, 2026
342492a
UCP/RNDV: Assert fragment mpool creation does not report quota exhaus…
amastbaum Oct 6, 2026
29be106
UCP/RNDV: small fix
amastbaum Oct 7, 2026
ca2f87c
UCP/RNDV: Find throttled requests of an endpoint without a per-EP list
amastbaum Oct 7, 2026
99d72b2
UCP/RNDV: Add rndv mtype flow-control tests for request reset and GET…
amastbaum Oct 8, 2026
8dd3ff5
UCP/RNDV: Merge master and keep the mtype FC state in a request field
amastbaum Oct 8, 2026
5b7dd76
Merge branch 'master' into add_throttling_to_rndv_fragment_requests
amastbaum Oct 9, 2026
dfe0c1d
UCP/RNDV: Add bidirectional rndv mtype flow-control test
amastbaum Oct 9, 2026
1c38b2a
UCP/RNDV: Abort a throttled rndv mtype request on fragment allocation…
amastbaum Oct 9, 2026
551f0e7
Merge branch 'master' into add_throttling_to_rndv_fragment_requests
amastbaum Oct 10, 2026
9f8df93
UCP/RNDV: Add rndv/get/mtype flow-control tests
amastbaum Oct 14, 2026
f7ceae1
Merge branch 'master' into add_throttling_to_rndv_fragment_requests
amastbaum Oct 18, 2026
45a77f1
UCP/RNDV: Pass the wakeup on when a woken PUT/GET takes a reserved fr…
amastbaum Oct 18, 2026
21d5bb8
UCP/RNDV: Always keep a fragment for PUT/GET
amastbaum Oct 19, 2026
58b3523
UCP/RNDV: Allocate rndv fragment mpools outside of the worker hash table
amastbaum Oct 19, 2026
e11b44b
Merge branch 'master' into add_throttling_to_rndv_fragment_requests
amastbaum Oct 19, 2026
ebc7ce7
UCP/RNDV: Initialize the fragment mpool failure ops in the constructor
amastbaum Oct 20, 2026
a695773
Merge branch 'master' into add_throttling_to_rndv_fragment_requests
amastbaum Nov 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/ucp/core/ucp_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,28 @@ static ucs_config_field_t ucp_context_config_table[] = {
"even if invalidation workflow isn't supported",
ucs_offsetof(ucp_context_config_t, rndv_errh_ppln_enable), UCS_CONFIG_TYPE_BOOL},

{"RNDV_FRAG_WORKER_MAX_MEM", "auto",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Help text does not match auto behavior. The description says ... or "inf" for no limit, but ucp_proto_rndv_frag_max_elems() returns UINT_MAX for both UCS_MEMUNITS_INF and UCS_MEMUNITS_AUTO, and auto is the default. So with the default value there is no limit at all, which the help text does not convey.

pls document that the default auto also means "no limit" (or make auto compute an actual limit) — as written it reads like only inf disables the cap, while today the feature is off by default.

"Maximum amount of memory a worker may use for rendezvous staging\n"
"fragments. Both \"auto\" and \"inf\" mean no limit. This setting has no\n"
"effect when PROTO_ENABLE=n. The same limit is applied independently to\n"
"each fragment memory type, and per device when available. It is\n"
"converted to a fragment count using RNDV_FRAG_SIZE. When the limit is\n"
"reached, further fragment requests are queued until fragments are\n"
"released. The limit is at least two fragments. See also\n"
"RNDV_FRAG_RTR_RATIO",
ucs_offsetof(ucp_context_config_t, rndv_frag_worker_max_mem),
UCS_CONFIG_TYPE_MEMUNITS},

{"RNDV_FRAG_RTR_RATIO", "0.8",
"Fraction of RNDV_FRAG_WORKER_MAX_MEM which fragments posted to receive\n"
"data (RTR) may use at once, in the range (0, 1). The rest is kept for\n"
"the put/get operations which move the data, so that they can always\n"
"make progress: an RTR fragment is released only when the peer's data\n"
"arrives, and the peer needs a fragment of its own to send it, so\n"
"without a reserve both peers could wait for each other forever",
ucs_offsetof(ucp_context_config_t, rndv_frag_rtr_ratio),
UCS_CONFIG_TYPE_POS_DOUBLE},

{"FLUSH_WORKER_EPS", "y",
"Enable flushing the worker by flushing its endpoints. Allows completing\n"
"the flush operation in a bounded time even if there are new requests on\n"
Expand Down Expand Up @@ -2785,6 +2807,14 @@ static ucs_status_t ucp_fill_config(ucp_context_h context,
goto err_free_alloc_methods;
}

if (UCS_CONFIG_DBL_IS_AUTO(context->config.ext.rndv_frag_rtr_ratio) ||
!(context->config.ext.rndv_frag_rtr_ratio < 1.0)) {
ucs_error("UCX_RNDV_FRAG_RTR_RATIO value %g is not in the range "
"(0, 1)", context->config.ext.rndv_frag_rtr_ratio);
status = UCS_ERR_INVALID_PARAM;
goto err_free_alloc_methods;
}

if (!ucp_dynamic_tl_switch_config_valid(&context->config.ext)) {
status = UCS_ERR_INVALID_PARAM;
goto err_free_alloc_methods;
Expand Down
5 changes: 4 additions & 1 deletion src/ucp/core/ucp_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ typedef struct ucp_context_config {
int rndv_shm_cuda_staging_force;
/** Enable error handling for rndv pipeline protocol */
int rndv_errh_ppln_enable;
/** Maximum memory for concurrent rndv fragments per worker (bytes) */
size_t rndv_frag_worker_max_mem;
/** Fraction of rndv_frag_worker_max_mem which RTR fragments may use */
double rndv_frag_rtr_ratio;
/** Threshold for using tag matching offload capabilities. Smaller buffers
* will not be posted to the transport. */
size_t tm_thresh;
Expand Down Expand Up @@ -807,7 +811,6 @@ ucp_context_print_transport_tables_enabled(ucp_context_h context)

return value == UCS_CONFIG_ON;
}

void ucp_context_memaccess_tl_bitmap(ucp_context_h context,
uint64_t mem_type_bitmap,
uint64_t md_reg_flags,
Expand Down
4 changes: 4 additions & 0 deletions src/ucp/core/ucp_ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <ucp/proto/proto_common.inl>
#include <ucp/proto/proto_debug.h>
#include <ucp/rndv/rndv.h>
#include <ucp/rndv/proto_rndv.h>
#include <ucp/stream/stream.h>
#include <ucp/core/ucp_listener.h>
#include <ucp/rma/rma.inl>
Expand Down Expand Up @@ -532,6 +533,7 @@ static int ucp_ep_remove_filter(const ucs_callbackq_elem_t *elem, void *arg)
ucp_ep_local_disconnect_progress_remove_filter(elem, arg) ||
ucp_ep_set_failed_remove_filter(elem, arg) ||
ucp_ep_wireup_eps_progress_filter(elem, arg) ||
ucp_proto_rndv_mtype_fc_reschedule_filter(elem, arg) ||
ucp_ep_tf_purge_remove_filter(elem, arg)) {
return 1;
}
Expand Down Expand Up @@ -5476,6 +5478,8 @@ void ucp_ep_reqs_purge(ucp_ep_h ucp_ep, ucs_status_t status)
ucp_ep_flush_state_t *flush_state;
ucp_request_t *req;

ucp_proto_rndv_mtype_fc_ep_purge(ucp_ep, status);

while (!ucs_hlist_is_empty(proto_reqs)) {
req = ucs_hlist_head_elem(proto_reqs, ucp_request_t, send.list);
if (ucp_ep->worker->context->config.ext.proto_enable) {
Expand Down
1 change: 1 addition & 0 deletions src/ucp/core/ucp_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ typedef struct ucp_rndv_mpool_priv {
ucp_worker_h worker;
ucs_memory_type_t mem_type;
ucs_sys_device_t sys_dev;
uint8_t pool; /* UCP_WORKER_RNDV_FRAG_POOL_* */
} ucp_rndv_mpool_priv_t;


Expand Down
26 changes: 26 additions & 0 deletions src/ucp/core/ucp_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ enum {
};


/**
* Fragment flow control state of a rndv request. Every rndv request must be
* initialized with ucp_proto_rndv_req_fc_init() when it is set up, since
* ucp_proto_rndv_mtype_fc_cancel() reads the state for any aborted or reset
* request.
*/
enum {
/* Not throttled */
UCP_REQUEST_RNDV_MTYPE_FC_NONE,
/* Waiting in the worker-level pending queue */
UCP_REQUEST_RNDV_MTYPE_FC_QUEUED,
/* Dequeued, a retry is scheduled from the progress loop */
UCP_REQUEST_RNDV_MTYPE_FC_RESCHED
};


/**
* Protocols enumerator to work with send request state
*/
Expand Down Expand Up @@ -322,6 +338,9 @@ struct ucp_request {
/* Data start offset of this request */
size_t offset;

/* UCP_REQUEST_RNDV_MTYPE_FC_* state */
uint8_t fc_state;

union {
/* Used by rndv/put and rndv/put/frag */
struct {
Expand All @@ -343,6 +362,13 @@ struct ucp_request {
ssize_t ack_data_size;
} ppln;

/* Used by rndv mtype requests while fc_state
* is not UCP_REQUEST_RNDV_MTYPE_FC_NONE */
struct {
/* Element in worker-level pending queue */
ucs_queue_elem_t queue_elem;
} fc;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Next PR: Maybe union with rkey_ptr


/* Used by rndv/rkey_ptr */
struct {
/* Element in queue for segmented RKEY ptr */
Expand Down
34 changes: 21 additions & 13 deletions src/ucp/core/ucp_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,19 @@ static ucs_stats_class_t ucp_worker_stats_class = {
.num_counters = UCP_WORKER_STAT_LAST,
.class_id = UCS_STATS_CLASS_ID_INVALID,
.counter_names = {
[UCP_WORKER_STAT_TAG_RX_EAGER_MSG] = "tag_rx_eager_msg",
[UCP_WORKER_STAT_TAG_RX_EAGER_SYNC_MSG] = "tag_rx_sync_msg",
[UCP_WORKER_STAT_TAG_RX_EAGER_CHUNK_EXP] = "tag_rx_eager_chunk_exp",
[UCP_WORKER_STAT_TAG_RX_EAGER_CHUNK_UNEXP] = "tag_rx_eager_chunk_unexp",
[UCP_WORKER_STAT_RNDV_RX_EXP] = "rndv_rx_exp",
[UCP_WORKER_STAT_RNDV_RX_UNEXP] = "rndv_rx_unexp",
[UCP_WORKER_STAT_RNDV_PUT_ZCOPY] = "rndv_put_zcopy",
[UCP_WORKER_STAT_RNDV_PUT_MTYPE_ZCOPY] = "rndv_put_mtype_zcopy",
[UCP_WORKER_STAT_RNDV_GET_ZCOPY] = "rndv_get_zcopy",
[UCP_WORKER_STAT_RNDV_RTR] = "rndv_rtr",
[UCP_WORKER_STAT_RNDV_RTR_MTYPE] = "rndv_rtr_mtype",
[UCP_WORKER_STAT_RNDV_RKEY_PTR] = "rndv_rkey_ptr"
[UCP_WORKER_STAT_TAG_RX_EAGER_MSG] = "tag_rx_eager_msg",
[UCP_WORKER_STAT_TAG_RX_EAGER_SYNC_MSG] = "tag_rx_sync_msg",
[UCP_WORKER_STAT_TAG_RX_EAGER_CHUNK_EXP] = "tag_rx_eager_chunk_exp",
[UCP_WORKER_STAT_TAG_RX_EAGER_CHUNK_UNEXP] = "tag_rx_eager_chunk_unexp",
[UCP_WORKER_STAT_RNDV_RX_EXP] = "rndv_rx_exp",
[UCP_WORKER_STAT_RNDV_RX_UNEXP] = "rndv_rx_unexp",
[UCP_WORKER_STAT_RNDV_PUT_ZCOPY] = "rndv_put_zcopy",
[UCP_WORKER_STAT_RNDV_PUT_MTYPE_ZCOPY] = "rndv_put_mtype_zcopy",
[UCP_WORKER_STAT_RNDV_GET_ZCOPY] = "rndv_get_zcopy",
[UCP_WORKER_STAT_RNDV_RTR] = "rndv_rtr",
[UCP_WORKER_STAT_RNDV_RTR_MTYPE] = "rndv_rtr_mtype",
[UCP_WORKER_STAT_RNDV_RKEY_PTR] = "rndv_rkey_ptr",
[UCP_WORKER_STAT_RNDV_MTYPE_FC_THROTTLED] = "rndv_mtype_fc_throttled"
Comment thread
tvegas1 marked this conversation as resolved.
Resolved
}
};
#endif
Expand Down Expand Up @@ -2217,7 +2218,8 @@ static void ucp_worker_destroy_mpools(ucp_worker_h worker)
if (!kh_exist(&worker->mpool_hash, iter)) {
continue;
}
ucs_mpool_cleanup(&kh_val(&worker->mpool_hash, iter), 1);
ucs_mpool_cleanup(kh_val(&worker->mpool_hash, iter), 1);
ucs_free(kh_val(&worker->mpool_hash, iter));
}

kh_destroy_inplace(ucp_worker_mpool_hash, &worker->mpool_hash);
Expand Down Expand Up @@ -2712,6 +2714,7 @@ ucs_status_t ucp_worker_create(ucp_context_h context,
unsigned name_length;
ucp_worker_h worker;
ucs_status_t status;
unsigned q_index;

worker = ucs_calloc(1, sizeof(*worker), "ucp worker");
if (worker == NULL) {
Expand Down Expand Up @@ -2743,6 +2746,11 @@ ucs_status_t ucp_worker_create(ucp_context_h context,
worker->counters.ep_closures = 0;
worker->counters.ep_failures = 0;

/* Initialize RNDV mtype flow control pending queues */
Comment thread
tvegas1 marked this conversation as resolved.
Resolved
Comment thread
tvegas1 marked this conversation as resolved.
Resolved
for (q_index = 0; q_index < UCP_WORKER_RNDV_FC_OP_LAST; q_index++) {
ucs_queue_head_init(&worker->rndv_mtype_fc.pending_q[q_index]);
}

/* Copy user flags, and mask-out unsupported flags for compatibility */
worker->flags = UCP_PARAM_VALUE(WORKER, params, flags, FLAGS, 0) &
UCS_MASK(UCP_WORKER_INTERNAL_FLAGS_SHIFT);
Expand Down
38 changes: 37 additions & 1 deletion src/ucp/core/ucp_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ enum {
UCP_WORKER_STAT_RNDV_RTR,
UCP_WORKER_STAT_RNDV_RTR_MTYPE,
UCP_WORKER_STAT_RNDV_RKEY_PTR,
UCP_WORKER_STAT_RNDV_MTYPE_FC_THROTTLED,

UCP_WORKER_STAT_LAST
};
Expand Down Expand Up @@ -223,15 +224,31 @@ KHASH_TYPE(ucp_worker_discard_uct_ep_hash, uct_ep_h, ucp_request_t*);
typedef khash_t(ucp_worker_discard_uct_ep_hash) ucp_worker_discard_uct_ep_hash_t;


/**
* Rendezvous fragment pools of a memory type and device. RTR requests use
* only the shared pool, while PUT/GET requests use the reserved pool first.
* This keeps fragments for PUT/GET: an RTR fragment is released only when
* the peer's data arrives, and the peer needs a fragment of its own to send
* it, so RTR fragments on both peers could otherwise wait for each other.
*/
typedef enum {
UCP_WORKER_RNDV_FRAG_POOL_SHARED,
UCP_WORKER_RNDV_FRAG_POOL_RESERVED
} ucp_worker_rndv_frag_pool_t;


typedef struct ucp_worker_mpool_key {
ucs_memory_type_t mem_type; /* memory type of the buffer pool */
ucs_sys_device_t sys_dev; /* identifier for the device,
UINT_MAX for default device */
uint8_t pool; /* UCP_WORKER_RNDV_FRAG_POOL_* */
} ucp_worker_mpool_key_t;


/* Hash map to find mpool by mpool key */
KHASH_TYPE(ucp_worker_mpool_hash, ucp_worker_mpool_key_t, ucs_mpool_t);
/* Pools are allocated separately, since fragments point to their pool and the
* hash table moves its values when it grows */
KHASH_TYPE(ucp_worker_mpool_hash, ucp_worker_mpool_key_t, ucs_mpool_t*);
typedef khash_t(ucp_worker_mpool_hash) ucp_worker_mpool_hash_t;


Expand Down Expand Up @@ -302,6 +319,19 @@ UCS_PTR_MAP_TYPE(request, 0);
UCS_ARRAY_DECLARE_TYPE(ucp_rkey_config_arr_t, unsigned, ucp_rkey_config_t*);


/**
* Rendezvous mtype flow-control operation types.
* Used as indices into the per-worker pending queue array.
* PUT and GET share the high-priority queue; RTR uses the low-priority queue.
*/
enum {
UCP_WORKER_RNDV_FC_OP_PUT = 0, /* GET/PUT (hi prio) */
UCP_WORKER_RNDV_FC_OP_GET = UCP_WORKER_RNDV_FC_OP_PUT, /* Same as PUT */
UCP_WORKER_RNDV_FC_OP_RTR = 1, /* RTR (lo prio) */
UCP_WORKER_RNDV_FC_OP_LAST = 2

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: these are priority levels, not ops — ..._OP_GET == ..._OP_PUT and ..._OP_LAST is really the number of queues. IMO naming them by priority (e.g. PRIO_HI/PRIO_LO/PRIO_LAST) makes the array indexing self-explanatory and avoids a silent queue/cancel mismatch if GET ever gets its own queue.

};


/**
* UCP worker (thread context).
*/
Expand Down Expand Up @@ -403,6 +433,12 @@ typedef struct ucp_worker {
uint64_t ep_failures;
} counters;

struct {
/* Pending queues indexed by UCP_WORKER_RNDV_FC_OP_*,
* ordered by descending priority (GET/PUT = 0, RTR = 1) */
ucs_queue_head_t pending_q[UCP_WORKER_RNDV_FC_OP_LAST];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

seems bot's comment is relevant, can be confirmed with test case, we might need to track pending req per (mem_type, sys_dev) / mpool, otherwise we could get deadlock where first pending req in line is woken up on the release of an unrelated mdesc and re-added at the end (also causing re-ordering). either somehow track per blocking mpool to avoid linear scan of the pending queue?

} rndv_mtype_fc;
Comment thread
tvegas1 marked this conversation as resolved.
Resolved

struct {
/* Usage tracker handle */
ucs_usage_tracker_h handle;
Expand Down
8 changes: 5 additions & 3 deletions src/ucp/core/ucp_worker.inl
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,20 @@ static UCS_F_ALWAYS_INLINE ucs_status_t ucp_worker_rkey_config_get(
static UCS_F_ALWAYS_INLINE khint_t
ucp_worker_mpool_hash_func(ucp_worker_mpool_key_t mpool_key)
{
return (khint_t)mpool_key.mem_type ^ (mpool_key.sys_dev << 8);
return (khint_t)mpool_key.mem_type ^ (mpool_key.sys_dev << 8) ^
(mpool_key.pool << 16);
}

static UCS_F_ALWAYS_INLINE int
ucp_worker_mpool_key_is_equal(ucp_worker_mpool_key_t mpool_key1,
ucp_worker_mpool_key_t mpool_key2)
{
return (mpool_key1.sys_dev == mpool_key2.sys_dev) &&
(mpool_key1.mem_type == mpool_key2.mem_type);
(mpool_key1.mem_type == mpool_key2.mem_type) &&
(mpool_key1.pool == mpool_key2.pool);
}

KHASH_IMPL(ucp_worker_mpool_hash, ucp_worker_mpool_key_t, ucs_mpool_t,
KHASH_IMPL(ucp_worker_mpool_hash, ucp_worker_mpool_key_t, ucs_mpool_t*,
1, ucp_worker_mpool_hash_func, ucp_worker_mpool_key_is_equal);

static UCS_F_ALWAYS_INLINE khint_t
Expand Down
1 change: 1 addition & 0 deletions src/ucp/rma/rma_rndv.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ static ucs_status_t ucp_proto_get_rndv_init(ucp_request_t *get_req,
rndv_req->send.rndv.remote_address = address;
rndv_req->send.rndv.rkey = get_req->send.rma.rkey;
rndv_req->send.rndv.offset = 0;
ucp_proto_rndv_req_fc_init(rndv_req);

UCS_PROFILE_CALL_VOID(ucp_datatype_iter_move,
&rndv_req->send.state.dt_iter,
Expand Down
4 changes: 4 additions & 0 deletions src/ucp/rndv/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ Defined in `rndv.h`:
pool growth.
- For GPU paths, always go through `rndv_mtype.inl` helpers and the
`memtype_cache`. Direct CUDA driver-API calls in this dir are wrong.
- Acquire mtype staging fragments with `ucp_proto_rndv_mtype_request_init()`
and return them with `ucp_proto_rndv_mtype_mdesc_release()`. A plain
`ucs_mpool_put()` on `send.rndv.mdesc` skips the flow-control wakeup and
can leave throttled requests queued forever.
- Pipelining (`ppln`) is a meta-protocol: it owns a parent request that
spawns child requests selected with `UCP_PROTO_SELECT_OP_FLAG_PPLN_FRAG`.
Never inline-progress a pipeline child — schedule it through the
Expand Down
Loading
Loading