Repository navigation
UCP/RNDV: Throttle rndv fragment requests #11062
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 all commits
bb7a13a
8d97668
30c5741
7716784
3eddbac
a9685bb
31eefc1
8275c36
2701d7f
7766da1
4e515c3
50b208f
ac696c7
e97bc99
45ef504
9c3bce9
5c67c59
1239821
a757e00
8c447d6
8f5f4ca
7627bcb
415a289
a84c684
aed4dc6
ea99ea1
5aacd1b
dce0ce4
0f877be
b548a0b
b802165
bc5cd27
398d835
e683f95
c974c97
89505d2
d52d74c
4c746e9
9b61860
9f30c96
231bdeb
b58d48d
586d57d
c356ccc
af47dde
3176441
d78e45d
7ab5730
e1be1df
b3ea1ee
65e9129
3096ac9
ac56848
2818753
c1efc3b
b61d637
c984f11
26499f3
5a8bdb4
342492a
29be106
ca2f87c
99d72b2
8dd3ff5
5b7dd76
dfe0c1d
1c38b2a
551f0e7
9f8df93
f7ceae1
45a77f1
21d5bb8
58b3523
e11b44b
ebc7ce7
a695773
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 |
|---|---|---|
|
|
@@ -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 | ||
| */ | ||
|
|
@@ -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 { | ||
|
|
@@ -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; | ||
|
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. Next PR: Maybe union with |
||
|
|
||
| /* Used by rndv/rkey_ptr */ | ||
| struct { | ||
| /* Element in queue for segmented RKEY ptr */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
| }; | ||
|
|
@@ -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; | ||
|
|
||
|
|
||
|
|
@@ -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 | ||
|
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. minor: these are priority levels, not ops — |
||
| }; | ||
|
|
||
|
|
||
| /** | ||
| * UCP worker (thread context). | ||
| */ | ||
|
|
@@ -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]; | ||
|
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. 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; | ||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||
|
|
||
| struct { | ||
| /* Usage tracker handle */ | ||
| ucs_usage_tracker_h handle; | ||
|
|
||
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.
Help text does not match
autobehavior. The description says... or "inf" for no limit, butucp_proto_rndv_frag_max_elems()returnsUINT_MAXfor bothUCS_MEMUNITS_INFandUCS_MEMUNITS_AUTO, andautois 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
autoalso means "no limit" (or makeautocompute an actual limit) — as written it reads like onlyinfdisables the cap, while today the feature is off by default.