This source file includes following definitions.
- opal_btl_usnic_check_rts
- opal_btl_usnic_post_segment
- opal_btl_usnic_post_ack
- opal_btl_usnic_endpoint_send_segment
- opal_btl_usnic_endpoint_enqueue_frag
- opal_btl_usnic_release_send_segment
1
2
3
4
5
6
7
8
9
10 #ifndef BTL_USNIC_SEND_H
11 #define BTL_USNIC_SEND_H
12
13 #include "btl_usnic.h"
14 #include "btl_usnic_frag.h"
15 #include "btl_usnic_ack.h"
16 #if MSGDEBUG1
17 #include "btl_usnic_util.h"
18 #endif
19
20
21
22
23
24 static inline void
25 opal_btl_usnic_check_rts(
26 opal_btl_usnic_endpoint_t *endpoint)
27 {
28
29
30
31
32
33
34
35 if (!endpoint->endpoint_ready_to_send &&
36 !opal_list_is_empty(&endpoint->endpoint_frag_send_queue) &&
37 endpoint->endpoint_send_credits > 0 &&
38 WINDOW_OPEN(endpoint)) {
39 opal_list_append(&endpoint->endpoint_module->endpoints_with_sends,
40 &endpoint->super);
41 endpoint->endpoint_ready_to_send = true;
42 #if MSGDEBUG1
43 opal_output(0, "make endpoint %p RTS\n", (void*)endpoint);
44 } else {
45 opal_output(0, "rts:%d empty:%d cred:%d open%d\n",
46 endpoint->endpoint_ready_to_send,
47 opal_list_is_empty(&endpoint->endpoint_frag_send_queue),
48 endpoint->endpoint_send_credits,
49 WINDOW_OPEN(endpoint));
50 #endif
51 }
52 }
53
54
55
56
57
58
59
60 static inline void
61 opal_btl_usnic_post_segment(
62 opal_btl_usnic_module_t *module,
63 opal_btl_usnic_endpoint_t *endpoint,
64 opal_btl_usnic_send_segment_t *sseg)
65 {
66 int ret;
67
68
69 opal_btl_usnic_channel_id_t channel_id = sseg->ss_channel;
70 opal_btl_usnic_channel_t *channel = &module->mod_channels[channel_id];
71
72 #if MSGDEBUG1
73 opal_output(0, "post_send: type=%s, ep=%p, remote_addr=%p, addr=%p, len=%"
74 PRIsize_t,
75 usnic_seg_type_str(sseg->ss_base.us_type),
76 (void*) channel->ep,
77 (void*) endpoint->endpoint_remote_addrs[channel_id],
78 (void*) sseg->ss_ptr,
79 sseg->ss_len);
80 #endif
81
82 assert(channel_id == USNIC_DATA_CHANNEL);
83 assert(channel->credits > 1);
84
85
86 ret = fi_send(channel->ep,
87 sseg->ss_ptr,
88 sseg->ss_len + mca_btl_usnic_component.prefix_send_offset,
89 NULL,
90 endpoint->endpoint_remote_addrs[channel_id],
91 sseg);
92 if (OPAL_UNLIKELY(0 != ret)) {
93 opal_btl_usnic_util_abort("fi_send() failed",
94 __FILE__, __LINE__);
95
96 }
97
98
99 if (sseg->ss_base.us_type != OPAL_BTL_USNIC_SEG_ACK) {
100 ++sseg->ss_send_posted;
101 ++sseg->ss_parent_frag->sf_seg_post_cnt;
102 }
103
104
105 ++module->stats.num_total_sends;
106 ++channel->num_channel_sends;
107 --channel->credits;
108 }
109
110
111
112
113
114
115
116 static inline void
117 opal_btl_usnic_post_ack(
118 opal_btl_usnic_module_t *module,
119 opal_btl_usnic_endpoint_t *endpoint,
120 opal_btl_usnic_send_segment_t *sseg)
121 {
122 int ret;
123
124
125 opal_btl_usnic_channel_id_t channel_id = sseg->ss_channel;
126 opal_btl_usnic_channel_t *channel = &module->mod_channels[channel_id];
127
128 #if MSGDEBUG1
129 opal_output(0, "post_send ACK: type=%s, ep=%p, remote_addr=%p, addr=%p, len=%"
130 PRIsize_t,
131 usnic_seg_type_str(sseg->ss_base.us_type),
132 (void*) channel->ep,
133 (void*) endpoint->endpoint_remote_addrs[channel_id],
134 (void*) sseg->ss_ptr,
135 sseg->ss_len);
136 #endif
137
138 assert(channel_id == USNIC_PRIORITY_CHANNEL);
139 assert(channel->credits > 1);
140
141 ret = fi_send(channel->ep,
142 sseg->ss_ptr,
143 sseg->ss_len + mca_btl_usnic_component.prefix_send_offset,
144 NULL,
145 endpoint->endpoint_remote_addrs[channel_id],
146 sseg);
147 if (OPAL_UNLIKELY(0 != ret)) {
148 opal_btl_usnic_util_abort("fi_send() failed",
149 __FILE__, __LINE__);
150
151 }
152
153
154 ++module->stats.num_total_sends;
155 ++channel->num_channel_sends;
156 --channel->credits;
157 }
158
159
160
161
162 static inline void
163 opal_btl_usnic_endpoint_send_segment(
164 opal_btl_usnic_module_t *module,
165 opal_btl_usnic_send_segment_t *sseg)
166 {
167 opal_btl_usnic_send_frag_t *frag;
168 opal_btl_usnic_endpoint_t *endpoint;
169 uint16_t sfi;
170
171 frag = sseg->ss_parent_frag;
172 endpoint = frag->sf_endpoint;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 assert(SEQ_GT(endpoint->endpoint_next_seq_to_send,
196 endpoint->endpoint_ack_seq_rcvd));
197 assert(WINDOW_OPEN(endpoint));
198
199
200 sseg->ss_base.us_btl_header->pkt_seq =
201 endpoint->endpoint_next_seq_to_send++;
202
203
204 sseg->ss_base.us_btl_header->put_addr =
205 frag->sf_base.uf_remote_seg[0].seg_addr.pval;
206
207
208 opal_btl_usnic_piggyback_ack(endpoint, sseg);
209
210 #if MSGDEBUG1
211 {
212 char local_ip[32];
213 char remote_ip[32];
214
215 opal_btl_usnic_snprintf_ipv4_addr(local_ip, sizeof(local_ip),
216 module->local_modex.ipv4_addr,
217 module->local_modex.netmask);
218 opal_btl_usnic_snprintf_ipv4_addr(remote_ip, sizeof(remote_ip),
219 endpoint->endpoint_remote_modex.ipv4_addr,
220 endpoint->endpoint_remote_modex.netmask);
221
222 opal_output(0, "--> Sending %s: seq: %" UDSEQ ", sender: 0x%016lx from device %s, IP %s, port %u, seg %p, room %d, wc len %u, remote IP %s, port %u",
223 (sseg->ss_parent_frag->sf_base.uf_type == OPAL_BTL_USNIC_FRAG_LARGE_SEND)?
224 "CHUNK" : "FRAG",
225 sseg->ss_base.us_btl_header->pkt_seq,
226 sseg->ss_base.us_btl_header->sender,
227 endpoint->endpoint_module->linux_device_name,
228 local_ip,
229 module->local_modex.ports[sseg->ss_channel],
230 (void*)sseg,
231 sseg->ss_hotel_room,
232 sseg->ss_ptr,
233 remote_ip,
234 endpoint->endpoint_remote_modex.ports[sseg->ss_channel]);
235 }
236 #endif
237
238
239 opal_btl_usnic_post_segment(module, endpoint, sseg);
240
241
242
243
244
245 sfi = WINDOW_SIZE_MOD(sseg->ss_base.us_btl_header->pkt_seq);
246 assert(NULL == endpoint->endpoint_sent_segs[sfi]);
247 endpoint->endpoint_sent_segs[sfi] = sseg;
248 sseg->ss_ack_pending = true;
249
250
251 --endpoint->endpoint_send_credits;
252
253
254 if (sseg->ss_parent_frag->sf_base.uf_type
255 == OPAL_BTL_USNIC_FRAG_LARGE_SEND) {
256 ++module->stats.num_chunk_sends;
257 } else {
258 ++module->stats.num_frag_sends;
259 }
260
261
262
263 opal_hotel_checkin_with_res(&endpoint->endpoint_hotel, sseg,
264 &sseg->ss_hotel_room);
265 }
266
267
268
269
270
271 static inline int
272 opal_btl_usnic_endpoint_enqueue_frag(
273 opal_btl_usnic_endpoint_t *endpoint,
274 opal_btl_usnic_send_frag_t *frag)
275 {
276 #if MSGDEBUG1
277 opal_output(0, "enq_frag: frag=%p, endpoint=%p, %s, len=%lu\n",
278 (void*)frag, (void*)endpoint,
279 usnic_frag_type(frag->sf_base.uf_type),
280 (long unsigned)frag->sf_base.uf_base.des_src->seg_len);
281 if (frag->sf_base.uf_type == OPAL_BTL_USNIC_FRAG_LARGE_SEND) {
282 opal_btl_usnic_large_send_frag_t *lfrag;
283 lfrag = (opal_btl_usnic_large_send_frag_t *)frag;
284 opal_output(0, " large size=%zd\n", lfrag->lsf_base.sf_size);
285 }
286 #endif
287
288
289 opal_list_append(&endpoint->endpoint_frag_send_queue,
290 &frag->sf_base.uf_base.super.super);
291
292
293 opal_btl_usnic_check_rts(endpoint);
294
295 return OPAL_SUCCESS;
296 }
297
298 static inline void
299 opal_btl_usnic_release_send_segment(
300 opal_btl_usnic_module_t *module,
301 opal_btl_usnic_send_frag_t *frag,
302 opal_btl_usnic_send_segment_t *sseg)
303 {
304
305
306
307 if (sseg->ss_base.us_type == OPAL_BTL_USNIC_SEG_CHUNK) {
308 opal_btl_usnic_chunk_segment_return(module, sseg);
309 }
310 }
311
312 void opal_btl_usnic_frag_complete(opal_btl_usnic_send_frag_t *frag);
313
314 void opal_btl_usnic_frag_send_complete(opal_btl_usnic_module_t *module,
315 opal_btl_usnic_send_segment_t *sseg);
316
317 void opal_btl_usnic_chunk_send_complete(opal_btl_usnic_module_t *module,
318 opal_btl_usnic_send_segment_t *sseg);
319
320 int
321 opal_btl_usnic_finish_put_or_send(
322 opal_btl_usnic_module_t *module,
323 opal_btl_usnic_endpoint_t *endpoint,
324 opal_btl_usnic_send_frag_t *frag,
325 mca_btl_base_tag_t tag)
326 __opal_attribute_noinline__;
327
328 #endif