@@ -364,6 +364,7 @@ static inline int mca_btl_base_am_rdma_advance(mca_btl_base_module_t *btl,
364
364
mca_btl_base_rdma_context_t * context ,
365
365
bool send_descriptor )
366
366
{
367
+ int ret ;
367
368
const size_t remaining = context -> total_size - context -> sent ;
368
369
369
370
if (0 == remaining ) {
@@ -401,7 +402,12 @@ static inline int mca_btl_base_am_rdma_advance(mca_btl_base_module_t *btl,
401
402
}
402
403
403
404
if (send_descriptor ) {
404
- return btl -> btl_send (btl , endpoint , descriptor , mca_btl_base_rdma_tag (hdr -> type ));
405
+ assert (0 != (descriptor -> des_flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK ));
406
+ ret = btl -> btl_send (btl , endpoint , descriptor , mca_btl_base_rdma_tag (hdr -> type ));
407
+ if (ret == 1 ) {
408
+ ret = OPAL_SUCCESS ;
409
+ }
410
+ return ret ;
405
411
}
406
412
407
413
/* queue for later to avoid btl_send in callback */
@@ -606,7 +612,14 @@ static int mca_btl_base_am_rdma_respond(mca_btl_base_module_t *btl,
606
612
607
613
send_descriptor -> des_cbfunc = NULL ;
608
614
615
+ /* There is no callback for the response descriptor, therefore it is
616
+ * safe to treat 0 and 1 return codes the same
617
+ */
609
618
int ret = btl -> btl_send (btl , endpoint , send_descriptor , mca_btl_base_rdma_resp_tag ());
619
+ if (ret == 1 ) {
620
+ ret = OPAL_SUCCESS ;
621
+ }
622
+
610
623
if (OPAL_UNLIKELY (OPAL_SUCCESS != ret )) {
611
624
* descriptor = send_descriptor ;
612
625
}
@@ -779,11 +792,12 @@ static int mca_btl_base_am_rdma_progress(void)
779
792
mca_btl_base_rdma_context_t *context = \
780
793
(mca_btl_base_rdma_context_t *) \
781
794
descriptor->descriptor->des_context; \
795
+ assert(0 != (descriptor->descriptor->des_flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK)); \
782
796
int ret = descriptor->btl->btl_send(descriptor->btl, \
783
797
descriptor->endpoint, \
784
798
descriptor->descriptor, \
785
799
mca_btl_base_rdma_tag(context->type)); \
786
- if (OPAL_SUCCESS == ret) { \
800
+ if (OPAL_SUCCESS == ret || 1 == ret ) { \
787
801
opal_list_remove_item(&default_module.queued_initiator_descriptors, \
788
802
&descriptor->super); \
789
803
} \
@@ -1132,5 +1146,28 @@ int mca_btl_base_am_rdma_init(mca_btl_base_module_t *btl)
1132
1146
OBJ_CONSTRUCT (& default_module , mca_btl_base_am_rdma_module_t );
1133
1147
}
1134
1148
1149
+ /* This section check whether we can claim support of remote completion.
1150
+ *
1151
+ * In terms of remote completion, we are mainly interested in put and atomic ops,
1152
+ * because get, atomics fops and atomic cswap support remote completion by their nature.
1153
+ *
1154
+ * For active message put (AM put), the target side will send a response, and the initiator
1155
+ * side will wait for the response to complete the put operation. Thus if AM put is based on send,
1156
+ * it support remote completion. (If AM put is based on get, it does not support remote
1157
+ * completion because the target side does not wait for get's completion to send response).
1158
+ *
1159
+ * active message RDMA/atomics does not implement atomic ops. User was suppose to
1160
+ * use atomic fops (unless the btl support atomic ops natively).
1161
+ *
1162
+ * In all, the conditions for AM rdma to claim support of remote completion are:
1163
+ * 1. AM put is enabled (which means the btl does not support put)
1164
+ * 2. AM put does not use get (so it must use send)
1165
+ * 3. btl does not have native atomics ops support.
1166
+ */
1167
+ if ((btl -> btl_flags & MCA_BTL_FLAGS_PUT_AM ) && !mca_btl_base_rdma_use_rdma_get (btl ) &&
1168
+ !(btl -> btl_flags & MCA_BTL_FLAGS_ATOMIC_OPS )) {
1169
+ btl -> btl_flags |= MCA_BTL_FLAGS_RDMA_REMOTE_COMPLETION ;
1170
+ }
1171
+
1135
1172
return OPAL_SUCCESS ;
1136
1173
}
0 commit comments