1 /*
2 * Copyright (c) 2013-2017 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33 #include "psmx.h"
34
_psmx_tagged_peek(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context,uint64_t flags)35 ssize_t _psmx_tagged_peek(struct fid_ep *ep, void *buf, size_t len,
36 void *desc, fi_addr_t src_addr,
37 uint64_t tag, uint64_t ignore,
38 void *context, uint64_t flags)
39 {
40 struct psmx_fid_ep *ep_priv;
41 psm_mq_status_t psm_status;
42 uint64_t psm_tag, psm_tagsel;
43 struct psmx_cq_event *event;
44 int err;
45
46 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
47
48 if (tag & ep_priv->domain->reserved_tag_bits) {
49 FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
50 "using reserved tag bits."
51 "tag=%lx. reserved_bits=%lx.\n", tag,
52 ep_priv->domain->reserved_tag_bits);
53 }
54
55 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
56 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
57
58 if (flags & (FI_CLAIM | FI_DISCARD))
59 return -FI_EOPNOTSUPP;
60
61 err = psm_mq_iprobe(ep_priv->domain->psm_mq, psm_tag, psm_tagsel,
62 &psm_status);
63
64 switch (err) {
65 case PSM_OK:
66 if (ep_priv->recv_cq) {
67 tag = psm_status.msg_tag;
68 len = psm_status.msg_length;
69 src_addr = 0;
70 event = psmx_cq_create_event(
71 ep_priv->recv_cq,
72 context, /* op_context */
73 NULL, /* buf */
74 flags|FI_RECV|FI_TAGGED,/* flags */
75 len, /* len */
76 0, /* data */
77 tag, /* tag */
78 len, /* olen */
79 0); /* err */
80
81 if (!event)
82 return -FI_ENOMEM;
83
84 event->source = src_addr;
85 psmx_cq_enqueue_event(ep_priv->recv_cq, event);
86 }
87 return 0;
88
89 case PSM_MQ_NO_COMPLETIONS:
90 if (ep_priv->recv_cq) {
91 event = psmx_cq_create_event(
92 ep_priv->recv_cq,
93 context, /* op_context */
94 NULL, /* buf */
95 flags|FI_RECV|FI_TAGGED,/* flags */
96 len, /* len */
97 0, /* data */
98 tag, /* tag */
99 len, /* olen */
100 -FI_ENOMSG); /* err */
101
102 if (!event)
103 return -FI_ENOMEM;
104
105 event->source = 0;
106 psmx_cq_enqueue_event(ep_priv->recv_cq, event);
107 }
108 return 0;
109
110 default:
111 return psmx_errno(err);
112 }
113 }
114
_psmx_tagged_recv(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context,uint64_t flags)115 ssize_t _psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len,
116 void *desc, fi_addr_t src_addr,
117 uint64_t tag, uint64_t ignore,
118 void *context, uint64_t flags)
119 {
120 struct psmx_fid_ep *ep_priv;
121 psm_mq_req_t psm_req;
122 uint64_t psm_tag, psm_tagsel;
123 struct fi_context *fi_context;
124 int err;
125
126 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
127
128 if (flags & FI_PEEK)
129 return _psmx_tagged_peek(ep, buf, len, desc, src_addr,
130 tag, ignore, context, flags);
131
132 if (flags & FI_TRIGGER) {
133 struct psmx_trigger *trigger;
134 struct fi_triggered_context *ctxt = context;
135
136 trigger = calloc(1, sizeof(*trigger));
137 if (!trigger)
138 return -FI_ENOMEM;
139
140 trigger->op = PSMX_TRIGGERED_TRECV;
141 trigger->cntr = container_of(ctxt->trigger.threshold.cntr,
142 struct psmx_fid_cntr, cntr);
143 trigger->threshold = ctxt->trigger.threshold.threshold;
144 trigger->trecv.ep = ep;
145 trigger->trecv.buf = buf;
146 trigger->trecv.len = len;
147 trigger->trecv.desc = desc;
148 trigger->trecv.src_addr = src_addr;
149 trigger->trecv.tag = tag;
150 trigger->trecv.ignore = ignore;
151 trigger->trecv.context = context;
152 trigger->trecv.flags = flags & ~FI_TRIGGER;
153
154 psmx_cntr_add_trigger(trigger->cntr, trigger);
155 return 0;
156 }
157
158 if (tag & ep_priv->domain->reserved_tag_bits) {
159 FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
160 "using reserved tag bits."
161 "tag=%lx. reserved_bits=%lx.\n", tag,
162 ep_priv->domain->reserved_tag_bits);
163 }
164
165 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
166 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
167
168 if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION)) {
169 fi_context = &ep_priv->nocomp_recv_context;
170 } else {
171 if (!context)
172 return -FI_EINVAL;
173
174 fi_context = context;
175 PSMX_CTXT_TYPE(fi_context) = PSMX_TRECV_CONTEXT;
176 PSMX_CTXT_USER(fi_context) = buf;
177 PSMX_CTXT_EP(fi_context) = ep_priv;
178 }
179
180 err = psm_mq_irecv(ep_priv->domain->psm_mq,
181 psm_tag, psm_tagsel, 0, /* flags */
182 buf, len, (void *)fi_context, &psm_req);
183
184 if (err != PSM_OK)
185 return psmx_errno(err);
186
187 if (fi_context == context)
188 PSMX_CTXT_REQ(fi_context) = psm_req;
189
190 return 0;
191 }
192
psmx_tagged_recv_no_flag_av_map(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)193 ssize_t psmx_tagged_recv_no_flag_av_map(struct fid_ep *ep, void *buf,
194 size_t len, void *desc,
195 fi_addr_t src_addr,
196 uint64_t tag, uint64_t ignore,
197 void *context)
198 {
199 struct psmx_fid_ep *ep_priv;
200 psm_mq_req_t psm_req;
201 uint64_t psm_tag, psm_tagsel;
202 struct fi_context *fi_context;
203 int err;
204
205 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
206
207 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
208 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
209
210 fi_context = context;
211 PSMX_CTXT_TYPE(fi_context) = PSMX_TRECV_CONTEXT;
212 PSMX_CTXT_USER(fi_context) = buf;
213 PSMX_CTXT_EP(fi_context) = ep_priv;
214
215 err = psm_mq_irecv(ep_priv->domain->psm_mq,
216 psm_tag, psm_tagsel, 0, /* flags */
217 buf, len, (void *)fi_context, &psm_req);
218 if (err != PSM_OK)
219 return psmx_errno(err);
220
221 PSMX_CTXT_REQ(fi_context) = psm_req;
222 return 0;
223 }
224
psmx_tagged_recv_no_flag_av_table(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)225 ssize_t psmx_tagged_recv_no_flag_av_table(struct fid_ep *ep, void *buf,
226 size_t len, void *desc,
227 fi_addr_t src_addr,
228 uint64_t tag, uint64_t ignore,
229 void *context)
230 {
231 struct psmx_fid_ep *ep_priv;
232 psm_mq_req_t psm_req;
233 uint64_t psm_tag, psm_tagsel;
234 struct fi_context *fi_context;
235 int err;
236
237 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
238
239 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
240 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
241
242 fi_context = context;
243 PSMX_CTXT_TYPE(fi_context) = PSMX_TRECV_CONTEXT;
244 PSMX_CTXT_USER(fi_context) = buf;
245 PSMX_CTXT_EP(fi_context) = ep_priv;
246
247 err = psm_mq_irecv(ep_priv->domain->psm_mq,
248 psm_tag, psm_tagsel, 0, /* flags */
249 buf, len, (void *)fi_context, &psm_req);
250 if (err != PSM_OK)
251 return psmx_errno(err);
252
253 PSMX_CTXT_REQ(fi_context) = psm_req;
254 return 0;
255 }
256
psmx_tagged_recv_no_event_av_map(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)257 ssize_t psmx_tagged_recv_no_event_av_map(struct fid_ep *ep, void *buf,
258 size_t len, void *desc,
259 fi_addr_t src_addr,
260 uint64_t tag, uint64_t ignore,
261 void *context)
262 {
263 struct psmx_fid_ep *ep_priv;
264 psm_mq_req_t psm_req;
265 uint64_t psm_tag, psm_tagsel;
266 struct fi_context *fi_context;
267 int err;
268
269 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
270
271 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
272 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
273
274 fi_context = &ep_priv->nocomp_recv_context;
275
276 err = psm_mq_irecv(ep_priv->domain->psm_mq,
277 psm_tag, psm_tagsel, 0, /* flags */
278 buf, len, (void *)fi_context, &psm_req);
279
280 return psmx_errno(err);
281 }
282
psmx_tagged_recv_no_event_av_table(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)283 ssize_t psmx_tagged_recv_no_event_av_table(struct fid_ep *ep, void *buf,
284 size_t len, void *desc,
285 fi_addr_t src_addr,
286 uint64_t tag, uint64_t ignore,
287 void *context)
288 {
289 struct psmx_fid_ep *ep_priv;
290 psm_mq_req_t psm_req;
291 uint64_t psm_tag, psm_tagsel;
292 struct fi_context *fi_context;
293 int err;
294
295 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
296
297 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
298 psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
299
300 fi_context = &ep_priv->nocomp_recv_context;
301
302 err = psm_mq_irecv(ep_priv->domain->psm_mq,
303 psm_tag, psm_tagsel, 0, /* flags */
304 buf, len, (void *)fi_context, &psm_req);
305
306 return psmx_errno(err);
307 }
308
psmx_tagged_recv(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)309 static ssize_t psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len, void *desc,
310 fi_addr_t src_addr,
311 uint64_t tag, uint64_t ignore, void *context)
312 {
313 struct psmx_fid_ep *ep_priv;
314
315 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
316
317 return _psmx_tagged_recv(ep, buf, len, desc, src_addr, tag, ignore,
318 context, ep_priv->rx_flags);
319 }
320
psmx_tagged_recvmsg(struct fid_ep * ep,const struct fi_msg_tagged * msg,uint64_t flags)321 static ssize_t psmx_tagged_recvmsg(struct fid_ep *ep, const struct fi_msg_tagged *msg,
322 uint64_t flags)
323 {
324 void *buf;
325 size_t len;
326
327 if (!msg || (msg->iov_count && !msg->msg_iov))
328 return -FI_EINVAL;
329
330 if (msg->iov_count > 1) {
331 return -FI_ENOSYS;
332 } else if (msg->iov_count) {
333 buf = msg->msg_iov[0].iov_base;
334 len = msg->msg_iov[0].iov_len;
335 } else {
336 buf = NULL;
337 len = 0;
338 }
339
340 return _psmx_tagged_recv(ep, buf, len,
341 msg->desc ? msg->desc[0] : NULL,
342 msg->addr, msg->tag, msg->ignore,
343 msg->context, flags);
344 }
345
psmx_tagged_recv_no_flag(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)346 static ssize_t psmx_tagged_recv_no_flag(struct fid_ep *ep, void *buf,
347 size_t len, void *desc, fi_addr_t src_addr,
348 uint64_t tag, uint64_t ignore,
349 void *context)
350 {
351 return psmx_tagged_recv_no_flag_av_map(
352 ep, buf, len, desc, src_addr,
353 tag, ignore, context);
354 }
355
psmx_tagged_recv_no_event(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)356 static ssize_t psmx_tagged_recv_no_event(struct fid_ep *ep, void *buf,
357 size_t len, void *desc, fi_addr_t src_addr,
358 uint64_t tag, uint64_t ignore,
359 void *context)
360 {
361 return psmx_tagged_recv_no_event_av_map(
362 ep, buf, len, desc, src_addr,
363 tag, ignore, context);
364 }
365
psmx_tagged_recvv(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)366 static ssize_t psmx_tagged_recvv(struct fid_ep *ep, const struct iovec *iov, void **desc,
367 size_t count, fi_addr_t src_addr,
368 uint64_t tag, uint64_t ignore, void *context)
369 {
370 void *buf;
371 size_t len;
372
373 if (count && !iov)
374 return -FI_EINVAL;
375
376 if (count > 1) {
377 return -FI_ENOSYS;
378 } else if (count) {
379 buf = iov[0].iov_base;
380 len = iov[0].iov_len;
381 } else {
382 buf = NULL;
383 len = 0;
384 }
385
386 return psmx_tagged_recv(ep, buf, len,
387 desc ? desc[0] : NULL, src_addr, tag, ignore, context);
388 }
389
psmx_tagged_recvv_no_flag(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)390 static ssize_t psmx_tagged_recvv_no_flag(struct fid_ep *ep, const struct iovec *iov,
391 void **desc, size_t count, fi_addr_t src_addr,
392 uint64_t tag, uint64_t ignore, void *context)
393 {
394 void *buf;
395 size_t len;
396
397 if (count && !iov)
398 return -FI_EINVAL;
399
400 if (count > 1) {
401 return -FI_ENOSYS;
402 } else if (count) {
403 buf = iov[0].iov_base;
404 len = iov[0].iov_len;
405 } else {
406 buf = NULL;
407 len = 0;
408 }
409
410 return psmx_tagged_recv_no_flag(ep, buf, len,
411 desc ? desc[0] : NULL, src_addr,
412 tag, ignore, context);
413 }
414
psmx_tagged_recvv_no_event(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t src_addr,uint64_t tag,uint64_t ignore,void * context)415 static ssize_t psmx_tagged_recvv_no_event(struct fid_ep *ep, const struct iovec *iov,
416 void **desc, size_t count, fi_addr_t src_addr,
417 uint64_t tag, uint64_t ignore, void *context)
418 {
419 void *buf;
420 size_t len;
421
422 if (count && !iov)
423 return -FI_EINVAL;
424
425 if (count > 1) {
426 return -FI_ENOSYS;
427 } else if (count) {
428 buf = iov[0].iov_base;
429 len = iov[0].iov_len;
430 } else {
431 buf = NULL;
432 len = 0;
433 }
434
435 return psmx_tagged_recv_no_event(ep, buf, len,
436 desc ? desc[0] : NULL, src_addr,
437 tag, ignore, context);
438 }
439
_psmx_tagged_send(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context,uint64_t flags)440 ssize_t _psmx_tagged_send(struct fid_ep *ep, const void *buf, size_t len,
441 void *desc, fi_addr_t dest_addr, uint64_t tag,
442 void *context, uint64_t flags)
443 {
444 struct psmx_fid_ep *ep_priv;
445 struct psmx_fid_av *av;
446 psm_epaddr_t psm_epaddr;
447 psm_mq_req_t psm_req;
448 uint64_t psm_tag;
449 struct fi_context *fi_context;
450 int err;
451 size_t idx;
452 int no_completion = 0;
453 struct psmx_cq_event *event;
454
455 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
456
457 if (flags & FI_TRIGGER) {
458 struct psmx_trigger *trigger;
459 struct fi_triggered_context *ctxt = context;
460
461 trigger = calloc(1, sizeof(*trigger));
462 if (!trigger)
463 return -FI_ENOMEM;
464
465 trigger->op = PSMX_TRIGGERED_TSEND;
466 trigger->cntr = container_of(ctxt->trigger.threshold.cntr,
467 struct psmx_fid_cntr, cntr);
468 trigger->threshold = ctxt->trigger.threshold.threshold;
469 trigger->tsend.ep = ep;
470 trigger->tsend.buf = buf;
471 trigger->tsend.len = len;
472 trigger->tsend.desc = desc;
473 trigger->tsend.dest_addr = dest_addr;
474 trigger->tsend.tag = tag;
475 trigger->tsend.context = context;
476 trigger->tsend.flags = flags & ~FI_TRIGGER;
477
478 psmx_cntr_add_trigger(trigger->cntr, trigger);
479 return 0;
480 }
481
482 if (tag & ep_priv->domain->reserved_tag_bits) {
483 FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
484 "using reserved tag bits."
485 "tag=%lx. reserved_bits=%lx.\n", tag,
486 ep_priv->domain->reserved_tag_bits);
487 }
488
489 av = ep_priv->av;
490 if (av && av->type == FI_AV_TABLE) {
491 idx = (size_t)dest_addr;
492 if (idx >= av->last)
493 return -FI_EINVAL;
494
495 psm_epaddr = av->psm_epaddrs[idx];
496 } else {
497 psm_epaddr = (psm_epaddr_t) dest_addr;
498 }
499
500 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
501
502 if ((flags & PSMX_NO_COMPLETION) ||
503 (ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
504 no_completion = 1;
505
506 if (flags & FI_INJECT) {
507 if (len > PSMX_INJECT_SIZE)
508 return -FI_EMSGSIZE;
509
510 err = psm_mq_send(ep_priv->domain->psm_mq, psm_epaddr, 0,
511 psm_tag, buf, len);
512
513 if (err != PSM_OK)
514 return psmx_errno(err);
515
516 if (ep_priv->send_cntr)
517 psmx_cntr_inc(ep_priv->send_cntr);
518
519 if (ep_priv->send_cq && !no_completion) {
520 event = psmx_cq_create_event(
521 ep_priv->send_cq,
522 context, (void *)buf, flags, len,
523 0 /* data */, psm_tag,
524 0 /* olen */,
525 0 /* err */);
526
527 if (event)
528 psmx_cq_enqueue_event(ep_priv->send_cq, event);
529 else
530 return -FI_ENOMEM;
531 }
532
533 return 0;
534 }
535
536 if (no_completion && !context) {
537 fi_context = &ep_priv->nocomp_send_context;
538 } else {
539 if (!context)
540 return -FI_EINVAL;
541
542 fi_context = context;
543 PSMX_CTXT_TYPE(fi_context) = PSMX_TSEND_CONTEXT;
544 PSMX_CTXT_USER(fi_context) = (void *)buf;
545 PSMX_CTXT_EP(fi_context) = ep_priv;
546 }
547
548 err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
549 psm_tag, buf, len, (void*)fi_context, &psm_req);
550
551 if (err != PSM_OK)
552 return psmx_errno(err);
553
554 if (fi_context == context)
555 PSMX_CTXT_REQ(fi_context) = psm_req;
556
557 return 0;
558 }
559
psmx_tagged_send_no_flag_av_map(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context)560 ssize_t psmx_tagged_send_no_flag_av_map(struct fid_ep *ep, const void *buf,
561 size_t len, void *desc,
562 fi_addr_t dest_addr, uint64_t tag,
563 void *context)
564 {
565 struct psmx_fid_ep *ep_priv;
566 psm_epaddr_t psm_epaddr;
567 psm_mq_req_t psm_req;
568 uint64_t psm_tag;
569 struct fi_context *fi_context;
570 int err;
571
572 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
573
574 psm_epaddr = (psm_epaddr_t) dest_addr;
575 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
576
577 fi_context = context;
578 PSMX_CTXT_TYPE(fi_context) = PSMX_TSEND_CONTEXT;
579 PSMX_CTXT_USER(fi_context) = (void *)buf;
580 PSMX_CTXT_EP(fi_context) = ep_priv;
581
582 err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
583 psm_tag, buf, len, (void*)fi_context, &psm_req);
584
585 if (err != PSM_OK)
586 return psmx_errno(err);
587
588 PSMX_CTXT_REQ(fi_context) = psm_req;
589 return 0;
590 }
591
psmx_tagged_send_no_flag_av_table(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context)592 ssize_t psmx_tagged_send_no_flag_av_table(struct fid_ep *ep, const void *buf,
593 size_t len, void *desc,
594 fi_addr_t dest_addr, uint64_t tag,
595 void *context)
596 {
597 struct psmx_fid_ep *ep_priv;
598 struct psmx_fid_av *av;
599 psm_epaddr_t psm_epaddr;
600 psm_mq_req_t psm_req;
601 uint64_t psm_tag;
602 struct fi_context *fi_context;
603 int err;
604 size_t idx;
605
606 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
607
608 av = ep_priv->av;
609 idx = (size_t)dest_addr;
610 if (idx >= av->last)
611 return -FI_EINVAL;
612
613 psm_epaddr = av->psm_epaddrs[idx];
614 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
615
616 fi_context = context;
617 PSMX_CTXT_TYPE(fi_context) = PSMX_TSEND_CONTEXT;
618 PSMX_CTXT_USER(fi_context) = (void *)buf;
619 PSMX_CTXT_EP(fi_context) = ep_priv;
620
621 err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
622 psm_tag, buf, len, (void*)fi_context, &psm_req);
623
624 if (err != PSM_OK)
625 return psmx_errno(err);
626
627 PSMX_CTXT_REQ(fi_context) = psm_req;
628 return 0;
629 }
630
psmx_tagged_send_no_event_av_map(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context)631 ssize_t psmx_tagged_send_no_event_av_map(struct fid_ep *ep, const void *buf,
632 size_t len, void *desc,
633 fi_addr_t dest_addr, uint64_t tag,
634 void *context)
635 {
636 struct psmx_fid_ep *ep_priv;
637 psm_epaddr_t psm_epaddr;
638 psm_mq_req_t psm_req;
639 uint64_t psm_tag;
640 struct fi_context *fi_context;
641 int err;
642
643 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
644
645 psm_epaddr = (psm_epaddr_t) dest_addr;
646 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
647
648 fi_context = &ep_priv->nocomp_send_context;
649
650 err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
651 psm_tag, buf, len, (void*)fi_context, &psm_req);
652
653 if (err != PSM_OK)
654 return psmx_errno(err);
655
656 return 0;
657 }
658
psmx_tagged_send_no_event_av_table(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context)659 ssize_t psmx_tagged_send_no_event_av_table(struct fid_ep *ep, const void *buf,
660 size_t len, void *desc,
661 fi_addr_t dest_addr, uint64_t tag,
662 void *context)
663 {
664 struct psmx_fid_ep *ep_priv;
665 struct psmx_fid_av *av;
666 psm_epaddr_t psm_epaddr;
667 psm_mq_req_t psm_req;
668 uint64_t psm_tag;
669 struct fi_context *fi_context;
670 int err;
671 size_t idx;
672
673 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
674
675 av = ep_priv->av;
676 idx = (size_t)dest_addr;
677 if (idx >= av->last)
678 return -FI_EINVAL;
679
680 psm_epaddr = av->psm_epaddrs[idx];
681 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
682
683 fi_context = &ep_priv->nocomp_send_context;
684
685 err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
686 psm_tag, buf, len, (void*)fi_context, &psm_req);
687
688 if (err != PSM_OK)
689 return psmx_errno(err);
690
691 return 0;
692 }
693
psmx_tagged_inject_no_flag_av_map(struct fid_ep * ep,const void * buf,size_t len,fi_addr_t dest_addr,uint64_t tag)694 ssize_t psmx_tagged_inject_no_flag_av_map(struct fid_ep *ep, const void *buf, size_t len,
695 fi_addr_t dest_addr, uint64_t tag)
696 {
697 struct psmx_fid_ep *ep_priv;
698 psm_epaddr_t psm_epaddr;
699 uint64_t psm_tag;
700 int err;
701
702 if (len > PSMX_INJECT_SIZE)
703 return -FI_EMSGSIZE;
704
705 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
706
707 psm_epaddr = (psm_epaddr_t) dest_addr;
708 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
709
710 err = psm_mq_send(ep_priv->domain->psm_mq, psm_epaddr, 0, psm_tag, buf, len);
711
712 if (err != PSM_OK)
713 return psmx_errno(err);
714
715 if (ep_priv->send_cntr)
716 psmx_cntr_inc(ep_priv->send_cntr);
717
718 return 0;
719 }
720
psmx_tagged_inject_no_flag_av_table(struct fid_ep * ep,const void * buf,size_t len,fi_addr_t dest_addr,uint64_t tag)721 ssize_t psmx_tagged_inject_no_flag_av_table(struct fid_ep *ep, const void *buf, size_t len,
722 fi_addr_t dest_addr, uint64_t tag)
723 {
724 struct psmx_fid_ep *ep_priv;
725 struct psmx_fid_av *av;
726 psm_epaddr_t psm_epaddr;
727 uint64_t psm_tag;
728 int err;
729 size_t idx;
730
731 if (len > PSMX_INJECT_SIZE)
732 return -FI_EMSGSIZE;
733
734 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
735
736 av = ep_priv->av;
737 idx = (size_t)dest_addr;
738 if (idx >= av->last)
739 return -FI_EINVAL;
740
741 psm_epaddr = av->psm_epaddrs[idx];
742 psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
743
744 err = psm_mq_send(ep_priv->domain->psm_mq, psm_epaddr, 0, psm_tag, buf, len);
745
746 if (err != PSM_OK)
747 return psmx_errno(err);
748
749 if (ep_priv->send_cntr)
750 psmx_cntr_inc(ep_priv->send_cntr);
751
752 return 0;
753 }
754
psmx_tagged_send(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dest_addr,uint64_t tag,void * context)755 static ssize_t psmx_tagged_send(struct fid_ep *ep, const void *buf, size_t len,
756 void *desc, fi_addr_t dest_addr,
757 uint64_t tag, void *context)
758 {
759 struct psmx_fid_ep *ep_priv;
760
761 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
762
763 return _psmx_tagged_send(ep, buf, len, desc, dest_addr, tag, context,
764 ep_priv->tx_flags);
765 }
766
psmx_tagged_sendmsg(struct fid_ep * ep,const struct fi_msg_tagged * msg,uint64_t flags)767 static ssize_t psmx_tagged_sendmsg(struct fid_ep *ep, const struct fi_msg_tagged *msg,
768 uint64_t flags)
769 {
770 void *buf;
771 size_t len;
772
773 if (!msg || (msg->iov_count && !msg->msg_iov))
774 return -FI_EINVAL;
775
776 if (msg->iov_count > 1) {
777 return -FI_ENOSYS;
778 } else if (msg->iov_count) {
779 buf = msg->msg_iov[0].iov_base;
780 len = msg->msg_iov[0].iov_len;
781 } else {
782 buf = NULL;
783 len = 0;
784 }
785
786 return _psmx_tagged_send(ep, buf, len,
787 msg->desc ? msg->desc[0] : NULL, msg->addr,
788 msg->tag, msg->context, flags);
789 }
790
psmx_tagged_sendv(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t tag,void * context)791 static ssize_t psmx_tagged_sendv(struct fid_ep *ep, const struct iovec *iov, void **desc,
792 size_t count, fi_addr_t dest_addr, uint64_t tag, void *context)
793 {
794 void *buf;
795 size_t len;
796
797 if (count && !iov)
798 return -FI_EINVAL;
799
800 if (count > 1) {
801 return -FI_ENOSYS;
802 } else if (count) {
803 buf = iov[0].iov_base;
804 len = iov[0].iov_len;
805 } else {
806 buf = NULL;
807 len = 0;
808 }
809
810 return psmx_tagged_send(ep, buf, len,
811 desc ? desc[0] : NULL, dest_addr, tag, context);
812 }
813
psmx_tagged_sendv_no_flag_av_map(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t tag,void * context)814 static ssize_t psmx_tagged_sendv_no_flag_av_map(struct fid_ep *ep, const struct iovec *iov,
815 void **desc, size_t count,
816 fi_addr_t dest_addr,
817 uint64_t tag, void *context)
818 {
819 void *buf;
820 size_t len;
821
822 if (count && !iov)
823 return -FI_EINVAL;
824
825 if (count > 1) {
826 return -FI_ENOSYS;
827 } else if (count) {
828 buf = iov[0].iov_base;
829 len = iov[0].iov_len;
830 } else {
831 buf = NULL;
832 len = 0;
833 }
834
835 return psmx_tagged_send_no_flag_av_map(ep, buf, len,
836 desc ? desc[0] : NULL, dest_addr,
837 tag, context);
838 }
839
psmx_tagged_sendv_no_flag_av_table(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t tag,void * context)840 static ssize_t psmx_tagged_sendv_no_flag_av_table(struct fid_ep *ep, const struct iovec *iov,
841 void **desc, size_t count,
842 fi_addr_t dest_addr,
843 uint64_t tag, void *context)
844 {
845 void *buf;
846 size_t len;
847
848 if (count && !iov)
849 return -FI_EINVAL;
850
851 if (count > 1) {
852 return -FI_ENOSYS;
853 } else if (count) {
854 buf = iov[0].iov_base;
855 len = iov[0].iov_len;
856 } else {
857 buf = NULL;
858 len = 0;
859 }
860
861 return psmx_tagged_send_no_flag_av_table(ep, buf, len,
862 desc ? desc[0] : NULL, dest_addr,
863 tag, context);
864 }
865
psmx_tagged_sendv_no_event_av_map(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t tag,void * context)866 static ssize_t psmx_tagged_sendv_no_event_av_map(struct fid_ep *ep, const struct iovec *iov,
867 void **desc, size_t count,
868 fi_addr_t dest_addr,
869 uint64_t tag, void *context)
870 {
871 void *buf;
872 size_t len;
873
874 if (count && !iov)
875 return -FI_EINVAL;
876
877 if (count > 1) {
878 return -FI_ENOSYS;
879 } else if (count) {
880 buf = iov[0].iov_base;
881 len = iov[0].iov_len;
882 } else {
883 buf = NULL;
884 len = 0;
885 }
886
887 return psmx_tagged_send_no_event_av_map(ep, buf, len,
888 desc ? desc[0] : NULL, dest_addr,
889 tag, context);
890 }
891
psmx_tagged_sendv_no_event_av_table(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t tag,void * context)892 static ssize_t psmx_tagged_sendv_no_event_av_table(struct fid_ep *ep, const struct iovec *iov,
893 void **desc, size_t count,
894 fi_addr_t dest_addr,
895 uint64_t tag, void *context)
896 {
897 void *buf;
898 size_t len;
899
900 if (count && !iov)
901 return -FI_EINVAL;
902
903 if (count > 1) {
904 return -FI_ENOSYS;
905 } else if (count) {
906 buf = iov[0].iov_base;
907 len = iov[0].iov_len;
908 } else {
909 buf = NULL;
910 len = 0;
911 }
912
913 return psmx_tagged_send_no_event_av_table(ep, buf, len,
914 desc ? desc[0] : NULL,
915 dest_addr, tag, context);
916 }
917
psmx_tagged_inject(struct fid_ep * ep,const void * buf,size_t len,fi_addr_t dest_addr,uint64_t tag)918 static ssize_t psmx_tagged_inject(struct fid_ep *ep, const void *buf, size_t len,
919 fi_addr_t dest_addr, uint64_t tag)
920 {
921 struct psmx_fid_ep *ep_priv;
922
923 ep_priv = container_of(ep, struct psmx_fid_ep, ep);
924
925 return _psmx_tagged_send(ep, buf, len, NULL, dest_addr, tag, NULL,
926 ep_priv->tx_flags | FI_INJECT | PSMX_NO_COMPLETION);
927 }
928
929 /* general case */
930 struct fi_ops_tagged psmx_tagged_ops = {
931 .size = sizeof(struct fi_ops_tagged),
932 .recv = psmx_tagged_recv,
933 .recvv = psmx_tagged_recvv,
934 .recvmsg = psmx_tagged_recvmsg,
935 .send = psmx_tagged_send,
936 .sendv = psmx_tagged_sendv,
937 .sendmsg = psmx_tagged_sendmsg,
938 .inject = psmx_tagged_inject,
939 .senddata = fi_no_tagged_senddata,
940 .injectdata = fi_no_tagged_injectdata,
941 };
942
943 /* op_flags=0, no event suppression, FI_AV_MAP */
944 struct fi_ops_tagged psmx_tagged_ops_no_flag_av_map = {
945 .size = sizeof(struct fi_ops_tagged),
946 .recv = psmx_tagged_recv_no_flag,
947 .recvv = psmx_tagged_recvv_no_flag,
948 .recvmsg = psmx_tagged_recvmsg,
949 .send = psmx_tagged_send_no_flag_av_map,
950 .sendv = psmx_tagged_sendv_no_flag_av_map,
951 .sendmsg = psmx_tagged_sendmsg,
952 .inject = psmx_tagged_inject_no_flag_av_map,
953 .senddata = fi_no_tagged_senddata,
954 .injectdata = fi_no_tagged_injectdata,
955 };
956
957 /* op_flags=0, no event suppression, FI_AV_TABLE */
958 struct fi_ops_tagged psmx_tagged_ops_no_flag_av_table = {
959 .size = sizeof(struct fi_ops_tagged),
960 .recv = psmx_tagged_recv_no_flag,
961 .recvv = psmx_tagged_recvv_no_flag,
962 .recvmsg = psmx_tagged_recvmsg,
963 .send = psmx_tagged_send_no_flag_av_table,
964 .sendv = psmx_tagged_sendv_no_flag_av_table,
965 .sendmsg = psmx_tagged_sendmsg,
966 .inject = psmx_tagged_inject_no_flag_av_table,
967 .senddata = fi_no_tagged_senddata,
968 .injectdata = fi_no_tagged_injectdata,
969 };
970
971 /* op_flags=0, event suppression, FI_AV_MAP */
972 struct fi_ops_tagged psmx_tagged_ops_no_event_av_map = {
973 .size = sizeof(struct fi_ops_tagged),
974 .recv = psmx_tagged_recv_no_event,
975 .recvv = psmx_tagged_recvv_no_event,
976 .recvmsg = psmx_tagged_recvmsg,
977 .send = psmx_tagged_send_no_event_av_map,
978 .sendv = psmx_tagged_sendv_no_event_av_map,
979 .sendmsg = psmx_tagged_sendmsg,
980 .inject = psmx_tagged_inject_no_flag_av_map,
981 .senddata = fi_no_tagged_senddata,
982 .injectdata = fi_no_tagged_injectdata,
983 };
984
985 /* op_flags=0, event suppression, FI_AV_TABLE */
986 struct fi_ops_tagged psmx_tagged_ops_no_event_av_table = {
987 .size = sizeof(struct fi_ops_tagged),
988 .recv = psmx_tagged_recv_no_event,
989 .recvv = psmx_tagged_recvv_no_event,
990 .recvmsg = psmx_tagged_recvmsg,
991 .send = psmx_tagged_send_no_event_av_table,
992 .sendv = psmx_tagged_sendv_no_event_av_table,
993 .sendmsg = psmx_tagged_sendmsg,
994 .inject = psmx_tagged_inject_no_flag_av_table,
995 .senddata = fi_no_tagged_senddata,
996 .injectdata = fi_no_tagged_injectdata,
997 };
998
999 /* op_flags=0, send event suppression, FI_AV_MAP */
1000 struct fi_ops_tagged psmx_tagged_ops_no_send_event_av_map = {
1001 .size = sizeof(struct fi_ops_tagged),
1002 .recv = psmx_tagged_recv_no_flag,
1003 .recvv = psmx_tagged_recvv_no_flag,
1004 .recvmsg = psmx_tagged_recvmsg,
1005 .send = psmx_tagged_send_no_event_av_map,
1006 .sendv = psmx_tagged_sendv_no_event_av_map,
1007 .sendmsg = psmx_tagged_sendmsg,
1008 .inject = psmx_tagged_inject_no_flag_av_map,
1009 .senddata = fi_no_tagged_senddata,
1010 .injectdata = fi_no_tagged_injectdata,
1011 };
1012
1013 /* op_flags=0, send event suppression, FI_AV_TABLE */
1014 struct fi_ops_tagged psmx_tagged_ops_no_send_event_av_table = {
1015 .size = sizeof(struct fi_ops_tagged),
1016 .recv = psmx_tagged_recv_no_flag,
1017 .recvv = psmx_tagged_recvv_no_flag,
1018 .recvmsg = psmx_tagged_recvmsg,
1019 .send = psmx_tagged_send_no_event_av_table,
1020 .sendv = psmx_tagged_sendv_no_event_av_table,
1021 .sendmsg = psmx_tagged_sendmsg,
1022 .inject = psmx_tagged_inject_no_flag_av_table,
1023 .senddata = fi_no_tagged_senddata,
1024 .injectdata = fi_no_tagged_injectdata,
1025 };
1026
1027 /* op_flags=0, recv event suppression, FI_AV_MAP */
1028 struct fi_ops_tagged psmx_tagged_ops_no_recv_event_av_map = {
1029 .size = sizeof(struct fi_ops_tagged),
1030 .recv = psmx_tagged_recv_no_event,
1031 .recvv = psmx_tagged_recvv_no_event,
1032 .recvmsg = psmx_tagged_recvmsg,
1033 .send = psmx_tagged_send_no_flag_av_map,
1034 .sendv = psmx_tagged_sendv_no_flag_av_map,
1035 .sendmsg = psmx_tagged_sendmsg,
1036 .inject = psmx_tagged_inject_no_flag_av_map,
1037 .senddata = fi_no_tagged_senddata,
1038 .injectdata = fi_no_tagged_injectdata,
1039 };
1040
1041 /* op_flags=0, recv event suppression, FI_AV_TABLE */
1042 struct fi_ops_tagged psmx_tagged_ops_no_recv_event_av_table = {
1043 .size = sizeof(struct fi_ops_tagged),
1044 .recv = psmx_tagged_recv_no_event,
1045 .recvv = psmx_tagged_recvv_no_event,
1046 .recvmsg = psmx_tagged_recvmsg,
1047 .send = psmx_tagged_send_no_flag_av_table,
1048 .sendv = psmx_tagged_sendv_no_flag_av_table,
1049 .sendmsg = psmx_tagged_sendmsg,
1050 .inject = psmx_tagged_inject_no_flag_av_table,
1051 .senddata = fi_no_tagged_senddata,
1052 .injectdata = fi_no_tagged_injectdata,
1053 };
1054