This source file includes following definitions.
- mca_btl_ugni_wait_list_append
- mca_btl_ugni_send
- mca_btl_ugni_sendi
- mca_btl_ugni_progress_send_wait_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include "btl_ugni.h"
17 #include "btl_ugni_frag.h"
18 #include "btl_ugni_smsg.h"
19 #include "btl_ugni_prepare.h"
20
21 void mca_btl_ugni_wait_list_append (mca_btl_ugni_module_t *ugni_module, mca_btl_base_endpoint_t *endpoint,
22 mca_btl_ugni_base_frag_t *frag)
23 {
24 BTL_VERBOSE(("wait-listing fragment %p to %s. endpoint state %d\n", (void*)frag, OPAL_NAME_PRINT(endpoint->peer_proc->proc_name), endpoint->state));
25
26 frag->base.des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
27
28
29 OPAL_THREAD_LOCK(&endpoint->lock);
30
31 opal_list_append (&endpoint->frag_wait_list, (opal_list_item_t *) frag);
32
33 OPAL_THREAD_UNLOCK(&endpoint->lock);
34
35 if (false == endpoint->wait_listed && MCA_BTL_UGNI_EP_STATE_CONNECTED == endpoint->state) {
36 OPAL_THREAD_LOCK(&ugni_module->ep_wait_list_lock);
37 if (false == endpoint->wait_listed) {
38 opal_list_append (&ugni_module->ep_wait_list, &endpoint->super);
39 endpoint->wait_listed = true;
40 }
41 OPAL_THREAD_UNLOCK(&ugni_module->ep_wait_list_lock);
42 }
43 }
44
45 int mca_btl_ugni_send (struct mca_btl_base_module_t *btl,
46 struct mca_btl_base_endpoint_t *endpoint,
47 struct mca_btl_base_descriptor_t *descriptor,
48 mca_btl_base_tag_t tag)
49 {
50 mca_btl_ugni_base_frag_t *frag = (mca_btl_ugni_base_frag_t *) descriptor;
51 size_t size = frag->segments[0].seg_len + frag->segments[1].seg_len;
52 mca_btl_ugni_module_t *ugni_module = (mca_btl_ugni_module_t *) btl;
53 int rc;
54
55
56 frag->hdr.send.lag = (tag << 24) | size;
57
58 BTL_VERBOSE(("btl/ugni sending descriptor %p from %d -> %d. length = %" PRIu64, (void *)descriptor,
59 OPAL_PROC_MY_NAME.vpid, endpoint->peer_proc->proc_name.vpid, size));
60
61 rc = mca_btl_ugni_check_endpoint_state (endpoint);
62 if (OPAL_UNLIKELY(OPAL_SUCCESS != rc || opal_list_get_size (&endpoint->frag_wait_list))) {
63 mca_btl_ugni_wait_list_append (ugni_module, endpoint, frag);
64 return OPAL_SUCCESS;
65 }
66
67
68
69 ++frag->ref_cnt;
70 frag->flags &= ~MCA_BTL_UGNI_FRAG_COMPLETE;
71
72 rc = mca_btl_ugni_send_frag (endpoint, frag);
73 if (OPAL_LIKELY(mca_btl_ugni_frag_check_complete (frag))) {
74
75 (void) mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
76
77 return 1;
78 }
79
80 if ((OPAL_SUCCESS == rc) && (frag->flags & MCA_BTL_UGNI_FRAG_BUFFERED) && (frag->flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP)) {
81
82 bool call_callback = !!(frag->flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK);
83 frag->flags &= ~MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
84
85 if (call_callback) {
86 frag->base.des_cbfunc(&ugni_module->super, frag->endpoint, &frag->base, rc);
87 }
88
89 (void) mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
90
91 return 1;
92 }
93
94
95
96 frag->base.des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
97
98 mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
99
100 if (OPAL_UNLIKELY(OPAL_ERR_OUT_OF_RESOURCE == rc)) {
101
102 mca_btl_ugni_wait_list_append (ugni_module, endpoint, frag);
103 rc = OPAL_SUCCESS;
104 }
105
106 return rc;
107 }
108
109 int mca_btl_ugni_sendi (struct mca_btl_base_module_t *btl,
110 struct mca_btl_base_endpoint_t *endpoint,
111 struct opal_convertor_t *convertor,
112 void *header, size_t header_size,
113 size_t payload_size, uint8_t order,
114 uint32_t flags, mca_btl_base_tag_t tag,
115 mca_btl_base_descriptor_t **descriptor)
116 {
117 size_t total_size = header_size + payload_size;
118 mca_btl_ugni_base_frag_t *frag = NULL;
119 size_t packed_size = payload_size;
120 int rc;
121
122 if (OPAL_UNLIKELY(opal_list_get_size (&endpoint->frag_wait_list))) {
123 if (NULL != descriptor) {
124 *descriptor = NULL;
125 }
126 return OPAL_ERR_OUT_OF_RESOURCE;
127 }
128
129 do {
130 BTL_VERBOSE(("btl/ugni isend sending fragment from %d -> %d. length = %" PRIu64
131 " endoint state %d", OPAL_PROC_MY_NAME.vpid, endpoint->peer_proc->proc_name.vpid,
132 payload_size + header_size, endpoint->state));
133
134 flags |= MCA_BTL_DES_FLAGS_BTL_OWNERSHIP;
135
136 if (0 == payload_size) {
137 frag = (mca_btl_ugni_base_frag_t *) mca_btl_ugni_prepare_src_send_nodata (btl, endpoint, order, header_size,
138 flags);
139 } else {
140 frag = (mca_btl_ugni_base_frag_t *) mca_btl_ugni_prepare_src_send_buffered (btl, endpoint, convertor, order,
141 header_size, &packed_size, flags);
142 }
143
144 assert (packed_size == payload_size);
145 if (OPAL_UNLIKELY(NULL == frag || OPAL_SUCCESS != mca_btl_ugni_check_endpoint_state (endpoint))) {
146 break;
147 }
148
149 frag->hdr.send.lag = (tag << 24) | total_size;
150 memcpy (frag->segments[0].seg_addr.pval, header, header_size);
151
152 rc = mca_btl_ugni_send_frag (endpoint, frag);
153 if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
154 break;
155 }
156
157 return OPAL_SUCCESS;
158 } while (0);
159
160 if (NULL != descriptor) {
161 *descriptor = &frag->base;
162 }
163
164 return OPAL_ERR_OUT_OF_RESOURCE;
165 }
166
167 int mca_btl_ugni_progress_send_wait_list (mca_btl_base_endpoint_t *endpoint)
168 {
169 mca_btl_ugni_base_frag_t *frag=NULL;
170 int rc;
171
172 do {
173 OPAL_THREAD_LOCK(&endpoint->lock);
174 frag = (mca_btl_ugni_base_frag_t *) opal_list_remove_first (&endpoint->frag_wait_list);
175 OPAL_THREAD_UNLOCK(&endpoint->lock);
176 if (NULL == frag) {
177 break;
178 }
179 if (OPAL_LIKELY(!(frag->flags & MCA_BTL_UGNI_FRAG_RESPONSE))) {
180 rc = mca_btl_ugni_send_frag (endpoint, frag);
181 } else {
182 rc = opal_mca_btl_ugni_smsg_send (frag, &frag->hdr.rdma, sizeof (frag->hdr.rdma),
183 NULL, 0, MCA_BTL_UGNI_TAG_RDMA_COMPLETE);
184 }
185
186 if (OPAL_UNLIKELY(OPAL_SUCCESS > rc)) {
187 if (OPAL_LIKELY(OPAL_ERR_OUT_OF_RESOURCE == rc)) {
188 OPAL_THREAD_LOCK(&endpoint->lock);
189 opal_list_prepend (&endpoint->frag_wait_list, (opal_list_item_t *) frag);
190 OPAL_THREAD_UNLOCK(&endpoint->lock);
191 } else {
192 mca_btl_ugni_frag_complete (frag, rc);
193 }
194 return rc;
195 }
196 } while(1);
197
198 return OPAL_SUCCESS;
199 }