1 /*
2  * Copyright (c) 2015-2017 Los Alamos National Security, LLC.
3  *                         All rights reserved.
4  * Copyright (c) 2015-2017 Cray Inc. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <getopt.h>
39 #include <poll.h>
40 #include <time.h>
41 #include <string.h>
42 #include <pthread.h>
43 #include <unistd.h>
44 #include <limits.h>
45 #include <assert.h>
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <inttypes.h>
50 
51 #include <criterion/criterion.h>
52 #include "gnix_rdma_headers.h"
53 #include "fi_ext_gni.h"
54 #include "gnix_util.h"
55 #include "common.h"
56 
57 #if 1
58 #define dbg_printf(...)
59 #else
60 #define dbg_printf(...)				\
61 	do {					\
62 		printf(__VA_ARGS__);		\
63 		fflush(stdout);			\
64 	} while (0)
65 #endif
66 
67 #define NUMEPS 2
68 
69 /* Note: Set to ~FI_NOTIFY_FLAGS_ONLY since this was written before api 1.5 */
70 static uint64_t mode_bits = ~FI_NOTIFY_FLAGS_ONLY;
71 static struct fid_fabric *fab;
72 static struct fid_domain *dom[NUMEPS];
73 struct fi_gni_ops_domain *gni_domain_ops[NUMEPS];
74 static struct fid_ep *ep[NUMEPS];
75 static struct fid_av *av[NUMEPS];
76 void *ep_name[NUMEPS];
77 fi_addr_t gni_addr[NUMEPS];
78 static struct fid_cq *msg_cq[NUMEPS];
79 static struct fi_info *fi[NUMEPS];
80 static struct fi_cq_attr cq_attr;
81 const char *api_cdm_id[NUMEPS] = { "5000", "5001" };
82 struct fi_info *hints[NUMEPS];
83 
84 #define BUF_SZ (1<<20)
85 char *target, *target_base;
86 char *source, *source_base;
87 char *uc_target;
88 char *uc_source;
89 struct fid_mr *rem_mr[NUMEPS], *loc_mr[NUMEPS];
90 uint64_t mr_key[NUMEPS];
91 
92 static struct fid_cntr *send_cntr[NUMEPS], *recv_cntr[NUMEPS];
93 static struct fi_cntr_attr cntr_attr = {
94 	.events = FI_CNTR_EVENTS_COMP,
95 	.flags = 0
96 };
97 static uint64_t sends[NUMEPS] = {0}, recvs[NUMEPS] = {0},
98 	send_errs[NUMEPS] = {0}, recv_errs[NUMEPS] = {0};
99 
rdm_api_setup_ep(uint32_t version,int mr_mode)100 static void rdm_api_setup_ep(uint32_t version, int mr_mode)
101 {
102 	int ret, i, j;
103 	struct fi_av_attr attr;
104 	size_t addrlen = 0;
105 
106 	/* Get info about fabric services with the provided hints */
107 	for (i = 0; i < NUMEPS; i++) {
108 		hints[i]->domain_attr->mr_mode = mr_mode;
109 
110 		ret = fi_getinfo(version, NULL, 0, 0, hints[i],
111 				 &fi[i]);
112 		cr_assert(!ret, "fi_getinfo");
113 	}
114 
115 	memset(&attr, 0, sizeof(attr));
116 	attr.type = FI_AV_MAP;
117 	attr.count = NUMEPS;
118 
119 	cq_attr.format = FI_CQ_FORMAT_TAGGED;
120 	cq_attr.size = 1024;
121 	cq_attr.wait_obj = 0;
122 
123 	/* 3x BUF_SZ for multi recv testing */
124 	target_base = malloc(GNIT_ALIGN_LEN(BUF_SZ * 3));
125 	assert(target_base);
126 	target = GNIT_ALIGN_BUFFER(char *, target_base);
127 
128 	source_base = malloc(GNIT_ALIGN_LEN(BUF_SZ));
129 	assert(source_base);
130 	source = GNIT_ALIGN_BUFFER(char *, source_base);
131 
132 	uc_target = malloc(BUF_SZ);
133 	assert(uc_target);
134 
135 	uc_source = malloc(BUF_SZ);
136 	assert(uc_source);
137 
138 	ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL);
139 	cr_assert(!ret, "fi_fabric");
140 
141 	for (i = 0; i < NUMEPS; i++) {
142 		ret = fi_domain(fab, fi[i], dom + i, NULL);
143 		cr_assert(!ret, "fi_domain");
144 
145 		ret = fi_open_ops(&dom[i]->fid, FI_GNI_DOMAIN_OPS_1,
146 				  0, (void **) (gni_domain_ops + i), NULL);
147 
148 		ret = fi_av_open(dom[i], &attr, av + i, NULL);
149 		cr_assert(!ret, "fi_av_open");
150 
151 		ret = fi_endpoint(dom[i], fi[i], ep + i, NULL);
152 		cr_assert(!ret, "fi_endpoint");
153 
154 		ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0);
155 		cr_assert(!ret, "fi_cq_open");
156 
157 		ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV);
158 		cr_assert(!ret, "fi_ep_bind");
159 
160 		ret = fi_getname(&ep[i]->fid, NULL, &addrlen);
161 		cr_assert(addrlen > 0);
162 
163 		ep_name[i] = malloc(addrlen);
164 		cr_assert(ep_name[i] != NULL);
165 
166 		ret = fi_getname(&ep[i]->fid, ep_name[i], &addrlen);
167 		cr_assert(ret == FI_SUCCESS);
168 	}
169 
170 	for (i = 0; i < NUMEPS; i++) {
171 		/* Insert all gni addresses into each av */
172 		for (j = 0; j < NUMEPS; j++) {
173 			ret = fi_av_insert(av[i], ep_name[j], 1, &gni_addr[j],
174 					   0, NULL);
175 			cr_assert(ret == 1);
176 		}
177 
178 		ret = fi_ep_bind(ep[i], &av[i]->fid, 0);
179 		cr_assert(!ret, "fi_ep_bind");
180 
181 		ret = fi_cntr_open(dom[i], &cntr_attr, send_cntr + i, 0);
182 		cr_assert(!ret, "fi_cntr_open");
183 
184 		ret = fi_ep_bind(ep[i], &send_cntr[i]->fid, FI_SEND);
185 		cr_assert(!ret, "fi_ep_bind");
186 
187 		ret = fi_cntr_open(dom[i], &cntr_attr, recv_cntr + i, 0);
188 		cr_assert(!ret, "fi_cntr_open");
189 
190 		ret = fi_ep_bind(ep[i], &recv_cntr[i]->fid, FI_RECV);
191 		cr_assert(!ret, "fi_ep_bind");
192 
193 		ret = fi_enable(ep[i]);
194 		cr_assert(!ret, "fi_ep_enable");
195 
196 		ret = fi_enable(ep[i]);
197 		cr_assert_eq(ret, -FI_EOPBADSTATE);
198 
199 
200 	}
201 
202 	for (i = 0; i < NUMEPS; i++) {
203 		int target_requested_key =
204 			USING_SCALABLE(fi[i]) ? (i * 2) : 0;
205 		int source_requested_key =
206 			USING_SCALABLE(fi[i]) ? (i * 2) + 1 : 0;
207 
208 		ret = fi_mr_reg(dom[i],
209 				  target,
210 				  3 * BUF_SZ,
211 				  FI_REMOTE_WRITE,
212 				  0,
213 				  target_requested_key,
214 				  0,
215 				  rem_mr + i,
216 				  &target);
217 		cr_assert_eq(ret, 0);
218 
219 		ret = fi_mr_reg(dom[i],
220 				  source,
221 				  BUF_SZ,
222 				  FI_REMOTE_WRITE,
223 				  0,
224 				  source_requested_key,
225 				  0,
226 				  loc_mr + i,
227 				  &source);
228 		cr_assert_eq(ret, 0);
229 
230 		if (USING_SCALABLE(fi[i])) {
231 			MR_ENABLE(rem_mr[i], target, 3 * BUF_SZ);
232 			MR_ENABLE(loc_mr[i], source, BUF_SZ);
233 		}
234 
235 		mr_key[i] = fi_mr_key(rem_mr[i]);
236 	}
237 }
238 
__rdm_api_setup(uint32_t version,int mr_mode)239 void __rdm_api_setup(uint32_t version, int mr_mode)
240 {
241 	int i;
242 
243 	SKIP_IF_SCALABLE_LT_1_5(version, mr_mode);
244 
245 	for (i = 0; i < NUMEPS; i++) {
246 		hints[i] = fi_allocinfo();
247 		cr_assert(hints[i], "fi_allocinfo");
248 
249 		hints[i]->domain_attr->cq_data_size = NUMEPS * 2;
250 		hints[i]->domain_attr->data_progress = FI_PROGRESS_AUTO;
251 		hints[i]->mode = mode_bits;
252 		hints[i]->fabric_attr->prov_name = strdup("gni");
253 	}
254 }
255 
rdm_api_setup_basic(void)256 static void rdm_api_setup_basic(void)
257 {
258 	__rdm_api_setup(fi_version(), GNIX_MR_BASIC);
259 }
260 
rdm_api_setup_scalable(void)261 static void rdm_api_setup_scalable(void)
262 {
263 	__rdm_api_setup(fi_version(), GNIX_MR_SCALABLE);
264 }
265 
api_setup(void)266 void api_setup(void)
267 {
268 }
269 
api_teardown(void)270 void api_teardown(void)
271 {
272 }
273 
rdm_api_teardown_common(bool unreg)274 static void rdm_api_teardown_common(bool unreg)
275 {
276 	int ret = 0, i = 0;
277 
278 	for (; i < NUMEPS; i++) {
279 		fi_close(&recv_cntr[i]->fid);
280 		fi_close(&send_cntr[i]->fid);
281 
282 		if (unreg) {
283 			fi_close(&loc_mr[i]->fid);
284 			fi_close(&rem_mr[i]->fid);
285 		}
286 
287 		ret = fi_close(&ep[i]->fid);
288 		cr_assert(!ret, "failure in closing ep.");
289 
290 		ret = fi_close(&msg_cq[i]->fid);
291 		cr_assert(!ret, "failure in send cq.");
292 
293 		ret = fi_close(&av[i]->fid);
294 		cr_assert(!ret, "failure in closing av.");
295 
296 		ret = fi_close(&dom[i]->fid);
297 		cr_assert(!ret, "failure in closing domain.");
298 
299 		fi_freeinfo(fi[i]);
300 		free(ep_name[i]);
301 		fi_freeinfo(hints[i]);
302 	}
303 
304 	free(uc_source);
305 	free(uc_target);
306 	free(target_base);
307 	free(source_base);
308 
309 	ret = fi_close(&fab->fid);
310 	cr_assert(!ret, "failure in closing fabric.");
311 }
312 
rdm_api_teardown(void)313 static void rdm_api_teardown(void)
314 {
315 	rdm_api_teardown_common(true);
316 }
317 
rdm_api_init_data(char * buf,int len,char seed)318 void rdm_api_init_data(char *buf, int len, char seed)
319 {
320 	int i;
321 
322 	for (i = 0; i < len; i++)
323 		buf[i] = seed++;
324 }
325 
rdm_api_check_data(char * buf1,char * buf2,int len)326 int rdm_api_check_data(char *buf1, char *buf2, int len)
327 {
328 	int i;
329 
330 	for (i = 0; i < len; i++) {
331 		if (buf1[i] != buf2[i]) {
332 			printf("data mismatch, elem: %d, exp: %hhx, act: %hhx\n"
333 			       , i, buf1[i], buf2[i]);
334 			return 0;
335 		}
336 	}
337 
338 	return 1;
339 }
340 
rdm_api_check_cqe(struct fi_cq_tagged_entry * cqe,void * ctx,uint64_t flags,void * addr,size_t len,uint64_t data,struct fid_ep * fid_ep)341 void rdm_api_check_cqe(struct fi_cq_tagged_entry *cqe, void *ctx,
342 		      uint64_t flags, void *addr, size_t len,
343 		      uint64_t data, struct fid_ep *fid_ep)
344 {
345 	struct gnix_fid_ep *gnix_ep = get_gnix_ep(fid_ep);
346 
347 	cr_assert(cqe->op_context == ctx, "CQE Context mismatch");
348 	cr_assert(cqe->flags == flags, "CQE flags mismatch");
349 
350 	if (flags & FI_RECV) {
351 		cr_assert(cqe->len == len, "CQE length mismatch");
352 		cr_assert(cqe->buf == addr, "CQE address mismatch");
353 
354 	/* TODO: Remove GNIX_ALLOW_FI_REMOTE_CQ_DATA and only check
355 	 *       flags for FI_RMA_EVENT */
356 	if (GNIX_ALLOW_FI_REMOTE_CQ_DATA(flags, gnix_ep->caps))
357 			cr_assert(cqe->data == data, "CQE data mismatch");
358 	} else {
359 		cr_assert(cqe->len == 0, "Invalid CQE length");
360 		cr_assert(cqe->buf == 0, "Invalid CQE address");
361 		cr_assert(cqe->data == 0, "Invalid CQE data");
362 	}
363 
364 	cr_assert(cqe->tag == 0, "Invalid CQE tag");
365 }
366 
rdm_api_check_cntrs(uint64_t s[],uint64_t r[],uint64_t s_e[],uint64_t r_e[])367 void rdm_api_check_cntrs(uint64_t s[], uint64_t r[], uint64_t s_e[],
368 			uint64_t r_e[])
369 {
370 	int i = 0;
371 
372 	for (; i < NUMEPS; i++) {
373 		sends[i] += s[i];
374 		recvs[i] += r[i];
375 		send_errs[i] += s_e[i];
376 		recv_errs[i] += r_e[i];
377 
378 		cr_assert(fi_cntr_read(send_cntr[i]) == sends[i],
379 			  "Bad send count");
380 		cr_assert(fi_cntr_read(recv_cntr[i]) == recvs[i],
381 			  "Bad recv count");
382 		cr_assert(fi_cntr_readerr(send_cntr[i]) == send_errs[i],
383 			  "Bad send err count");
384 		cr_assert(fi_cntr_readerr(recv_cntr[i]) == recv_errs[i],
385 			  "Bad recv err count");
386 	}
387 }
388 
389 /*******************************************************************************
390  * Test MSG functions
391  ******************************************************************************/
392 
393 #define MSG_SEND_ALLOWED(caps) \
394 	((caps & FI_MSG) && ((caps & FI_SEND) || !(caps & FI_RECV)))
395 #define MSG_RECV_ALLOWED(caps) \
396 	((caps & FI_MSG) && ((caps & FI_RECV) || !(caps & FI_SEND)))
397 #define TAG_SEND_ALLOWED(caps) \
398 	((caps & FI_TAGGED) && ((caps & FI_SEND) || !(caps & FI_RECV)))
399 #define TAG_RECV_ALLOWED(caps) \
400 	((caps & FI_TAGGED) && ((caps & FI_RECV) || !(caps & FI_SEND)))
401 #define WRITE_ALLOWED(caps, rcaps)                       \
402 	((caps & FI_RMA) &&                              \
403 	 ((caps & FI_WRITE) || !(caps & FI_READ)) &&     \
404 	 ((rcaps & FI_RMA) || (rcaps & FI_REMOTE_WRITE)) \
405 	)
406 #define READ_ALLOWED(caps, rcaps)                                \
407 	((caps & FI_RMA) &&                                      \
408 	 ((caps & FI_READ) || !(caps & FI_WRITE)) &&             \
409 	 (((rcaps & FI_RMA) &&                                   \
410 	   !(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_WRITE))) || \
411 	  (rcaps & FI_REMOTE_READ)                               \
412 	 )                                                       \
413 	)
write_allowed(uint64_t rma_amo,uint64_t caps,uint64_t rcaps)414 static int write_allowed(uint64_t rma_amo, uint64_t caps, uint64_t rcaps)
415 {
416 	dbg_printf("write %s caps:%s, rcaps:%s\n",
417 		   fi_tostr(&rma_amo, FI_TYPE_CAPS),
418 		   fi_tostr(&caps, FI_TYPE_CAPS),
419 		   fi_tostr(&rcaps, FI_TYPE_CAPS));
420 	if ((caps & rma_amo) &&
421 	    ((caps & FI_WRITE) || !(caps & FI_READ))) {
422 		if ((rcaps & rma_amo) &&
423 		    ((rcaps & FI_REMOTE_WRITE) ||
424 		      (!(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_READ)))
425 		    )
426 		   ) {
427 			return 1;
428 		}
429 	}
430 	return 0;
431 }
432 
read_allowed(uint64_t rma_amo,uint64_t caps,uint64_t rcaps)433 static int read_allowed(uint64_t rma_amo, uint64_t caps, uint64_t rcaps)
434 {
435 	dbg_printf("read %s caps:%s, rcaps:%s\n",
436 		   fi_tostr(&rma_amo, FI_TYPE_CAPS),
437 		   fi_tostr(&caps, FI_TYPE_CAPS),
438 		   fi_tostr(&rcaps, FI_TYPE_CAPS));
439 	if ((caps & rma_amo) &&
440 	    ((caps & FI_READ) || !(caps & FI_WRITE))) {
441 		if ((rcaps & rma_amo) &&
442 		    ((rcaps & FI_REMOTE_READ) ||
443 		     (!(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_WRITE)))
444 		    )
445 		   ) {
446 			return 1;
447 		}
448 	}
449 	return 0;
450 }
451 
452 TestSuite(rdm_api_basic,
453 	  .init = rdm_api_setup_basic,
454 	  .fini = rdm_api_teardown);
455 
456 TestSuite(rdm_api_scalable,
457 	  .init = rdm_api_setup_scalable,
458 	 .fini = rdm_api_teardown);
459 
460 /*
461  * ssize_t fi_send(struct fid_ep *ep, void *buf, size_t len,
462  *		void *desc, fi_addr_t dest_addr, void *context);
463  *
464  * ssize_t fi_recv(struct fid_ep *ep, void * buf, size_t len,
465  *		void *desc, fi_addr_t src_addr, void *context);
466  */
api_send_recv(int len)467 void api_send_recv(int len)
468 {
469 	ssize_t sz;
470 	uint64_t caps = fi[0]->caps;
471 
472 	rdm_api_init_data(source, len, 0xab);
473 	rdm_api_init_data(target, len, 0);
474 
475 	sz = fi_send(ep[0], source, len, loc_mr[0], gni_addr[1], target);
476 	if (MSG_SEND_ALLOWED(caps)) {
477 		cr_assert(sz == 0, "fi_send failed caps:0x%lx err:%ld",
478 			  caps, sz);
479 	} else {
480 		cr_assert(sz < 0, "fi_send should fail caps:0x%lx err:%ld",
481 			  caps, sz);
482 	}
483 
484 	sz = fi_recv(ep[1], target, len, rem_mr[1], gni_addr[0], source);
485 	if (MSG_RECV_ALLOWED(caps)) {
486 		cr_assert(sz == 0, "fi_recv failed caps:0x%lx err:%ld",
487 			  caps, sz);
488 	} else {
489 		cr_assert(sz < 0, "fi_recv should fail caps:0x%lx err:%ld",
490 			  caps, sz);
491 	}
492 }
493 
Test(api,dom_caps)494 Test(api, dom_caps)
495 {
496 	int ret;
497 
498 	hints[0] = fi_allocinfo();
499 	cr_assert(hints[0], "fi_allocinfo");
500 
501 	hints[0]->mode = mode_bits;
502 	hints[0]->fabric_attr->prov_name = strdup("gni");
503 	hints[0]->domain_attr->mr_mode = GNIX_DEFAULT_MR_MODE;
504 
505 	/* we only support REMOTE_COMM */
506 	hints[0]->domain_attr->caps = FI_LOCAL_COMM;
507 	ret = fi_getinfo(fi_version(), NULL, 0, 0, hints[0], &fi[0]);
508 	cr_assert_eq(ret, -FI_ENODATA, "fi_getinfo");
509 
510 	hints[0]->domain_attr->caps = FI_REMOTE_COMM;
511 	ret = fi_getinfo(fi_version(), NULL, 0, 0, hints[0], &fi[0]);
512 	cr_assert_eq(ret, 0, "fi_getinfo");
513 
514 	fi_freeinfo(fi[0]);
515 
516 	hints[0]->domain_attr->mr_mode = FI_MR_UNSPEC;
517 	ret = fi_getinfo(FI_VERSION(1, 0), NULL, 0, 0, hints[0], &fi[0]);
518 	cr_assert_eq(ret, 0, "fi_getinfo");
519 
520 	fi_freeinfo(hints[0]);
521 	fi_freeinfo(fi[0]);
522 }
523 
__msg_no_caps(uint32_t version,int mr_mode)524 static inline void __msg_no_caps(uint32_t version, int mr_mode)
525 {
526 	hints[0]->caps = 0;
527 	hints[1]->caps = 0;
528 	rdm_api_setup_ep(version, mr_mode);
529 	api_send_recv(BUF_SZ);
530 }
531 
Test(rdm_api_basic,msg_no_caps)532 Test(rdm_api_basic, msg_no_caps)
533 {
534 	__msg_no_caps(fi_version(), GNIX_MR_BASIC);
535 }
536 
Test(rdm_api_scalable,msg_no_caps)537 Test(rdm_api_scalable, msg_no_caps)
538 {
539 	__msg_no_caps(fi_version(), GNIX_MR_SCALABLE);
540 }
541 
__msg_send_rcv(uint32_t version,int mr_mode)542 static inline void __msg_send_rcv(uint32_t version, int mr_mode)
543 {
544 	hints[0]->caps = FI_MSG;
545 	hints[1]->caps = FI_MSG;
546 	rdm_api_setup_ep(version, mr_mode);
547 	api_send_recv(BUF_SZ);
548 }
549 
Test(rdm_api_basic,msg_send_rcv)550 Test(rdm_api_basic, msg_send_rcv)
551 {
552 	__msg_send_rcv(fi_version(), GNIX_MR_BASIC);
553 }
554 
Test(rdm_api_scalable,msg_send_rcv)555 Test(rdm_api_scalable, msg_send_rcv)
556 {
557 	__msg_send_rcv(fi_version(), GNIX_MR_SCALABLE);
558 }
559 
__msg_send_only(uint32_t version,int mr_mode)560 static inline void __msg_send_only(uint32_t version, int mr_mode)
561 {
562 	hints[0]->caps = FI_MSG | FI_SEND;
563 	hints[1]->caps = FI_MSG | FI_SEND;
564 	rdm_api_setup_ep(version, mr_mode);
565 	api_send_recv(BUF_SZ);
566 }
567 
Test(rdm_api_basic,msg_send_only)568 Test(rdm_api_basic, msg_send_only)
569 {
570 	__msg_send_only(fi_version(), GNIX_MR_BASIC);
571 }
572 
Test(rdm_api_scalable,msg_send_only)573 Test(rdm_api_scalable, msg_send_only)
574 {
575 	__msg_send_only(fi_version(), GNIX_MR_SCALABLE);
576 }
577 
__msg_recv_only(uint32_t version,int mr_mode)578 static inline void __msg_recv_only(uint32_t version, int mr_mode)
579 {
580 	hints[0]->caps = FI_MSG | FI_RECV;
581 	hints[1]->caps = FI_MSG | FI_RECV;
582 	rdm_api_setup_ep(version, mr_mode);
583 	api_send_recv(BUF_SZ);
584 }
585 
Test(rdm_api_basic,msg_recv_only)586 Test(rdm_api_basic, msg_recv_only)
587 {
588 	__msg_recv_only(fi_version(), GNIX_MR_BASIC);
589 }
590 
Test(rdm_api_scalable,msg_recv_only)591 Test(rdm_api_scalable, msg_recv_only)
592 {
593 	__msg_recv_only(fi_version(), GNIX_MR_SCALABLE);
594 }
595 
__msg_send_rcv_w_tagged(uint32_t version,int mr_mode)596 static inline void __msg_send_rcv_w_tagged(uint32_t version, int mr_mode)
597 {
598 	hints[0]->caps = FI_TAGGED;
599 	hints[1]->caps = FI_TAGGED;
600 	rdm_api_setup_ep(version, mr_mode);
601 	api_send_recv(BUF_SZ);
602 }
603 
Test(rdm_api_basic,msg_send_rcv_w_tagged)604 Test(rdm_api_basic, msg_send_rcv_w_tagged)
605 {
606 	__msg_send_rcv_w_tagged(fi_version(), GNIX_MR_BASIC);
607 }
608 
Test(rdm_api_scalable,msg_send_rcv_w_tagged)609 Test(rdm_api_scalable, msg_send_rcv_w_tagged)
610 {
611 	__msg_send_rcv_w_tagged(fi_version(), GNIX_MR_SCALABLE);
612 }
613 
api_tagged_send_recv(int len)614 void api_tagged_send_recv(int len)
615 {
616 	ssize_t sz;
617 	uint64_t caps = fi[0]->caps;
618 
619 	rdm_api_init_data(source, len, 0xab);
620 	rdm_api_init_data(target, len, 0);
621 
622 	sz = fi_tsend(ep[0], source, len, loc_mr, gni_addr[1], len, target);
623 	if (TAG_SEND_ALLOWED(caps)) {
624 		cr_assert(sz == 0, "fi_tsend failed caps:0x%lx err:%ld",
625 			  caps, sz);
626 	} else {
627 		cr_assert(sz < 0, "fi_tsend should fail caps:0x%lx err:%ld",
628 			  caps, sz);
629 	}
630 
631 	sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
632 	if (TAG_RECV_ALLOWED(caps)) {
633 		cr_assert(sz == 0, "fi_trecv failed caps:0x%lx err:%ld",
634 			  caps, sz);
635 	} else {
636 		cr_assert(sz < 0, "fi_trecv should fail caps:0x%lx err:%ld",
637 			  caps, sz);
638 	}
639 }
640 
__tsend(uint32_t version,int mr_mode)641 static inline void __tsend(uint32_t version, int mr_mode)
642 {
643 	hints[0]->caps = FI_TAGGED;
644 	hints[1]->caps = FI_TAGGED;
645 	rdm_api_setup_ep(version, mr_mode);
646 	api_tagged_send_recv(BUF_SZ);
647 }
648 
Test(rdm_api_basic,tsend)649 Test(rdm_api_basic, tsend)
650 {
651 	__tsend(fi_version(), GNIX_MR_BASIC);
652 }
653 
Test(rdm_api_scalable,tsend)654 Test(rdm_api_scalable, tsend)
655 {
656 	__tsend(fi_version(), GNIX_MR_SCALABLE);
657 }
658 
__tsend_only(uint32_t version,int mr_mode)659 static inline void __tsend_only(uint32_t version, int mr_mode)
660 {
661 	hints[0]->caps = FI_TAGGED | FI_SEND;
662 	hints[1]->caps = FI_TAGGED | FI_SEND;
663 	rdm_api_setup_ep(version, mr_mode);
664 	api_tagged_send_recv(BUF_SZ);
665 }
666 
Test(rdm_api_basic,tsend_only)667 Test(rdm_api_basic, tsend_only)
668 {
669 	__tsend_only(fi_version(), GNIX_MR_BASIC);
670 }
671 
Test(rdm_api_scalable,tsend_only)672 Test(rdm_api_scalable, tsend_only)
673 {
674 	__tsend_only(fi_version(), GNIX_MR_SCALABLE);
675 }
676 
__trecv_only(uint32_t version,int mr_mode)677 static inline void __trecv_only(uint32_t version, int mr_mode)
678 {
679 	hints[0]->caps = FI_TAGGED | FI_RECV;
680 	hints[1]->caps = FI_TAGGED | FI_RECV;
681 	rdm_api_setup_ep(version, mr_mode);
682 	api_tagged_send_recv(BUF_SZ);
683 }
684 
Test(rdm_api_basic,trecv_only)685 Test(rdm_api_basic, trecv_only)
686 {
687 	__trecv_only(fi_version(), GNIX_MR_BASIC);
688 }
689 
Test(rdm_api_scalable,trecv_only)690 Test(rdm_api_scalable, trecv_only)
691 {
692 	__trecv_only(fi_version(), GNIX_MR_SCALABLE);
693 }
694 
__tsend_rcv_w_msg(uint32_t version,int mr_mode)695 static inline void __tsend_rcv_w_msg(uint32_t version, int mr_mode)
696 {
697 	hints[0]->caps = FI_MSG;
698 	hints[1]->caps = FI_MSG;
699 	rdm_api_setup_ep(version, mr_mode);
700 	api_tagged_send_recv(BUF_SZ);
701 }
702 
Test(rdm_api_basic,tsend_rcv_w_msg)703 Test(rdm_api_basic, tsend_rcv_w_msg)
704 {
705 	__tsend_rcv_w_msg(fi_version(), GNIX_MR_BASIC);
706 }
707 
Test(rdm_api_scalable,tsend_rcv_w_msg)708 Test(rdm_api_scalable, tsend_rcv_w_msg)
709 {
710 	__tsend_rcv_w_msg(fi_version(), GNIX_MR_SCALABLE);
711 }
712 
713 #define READ_CTX 0x4e3dda1aULL
api_write_read(int len)714 void api_write_read(int len)
715 {
716 	int ret;
717 	struct fi_cq_tagged_entry cqe;
718 	struct fi_cq_err_entry err_cqe = {0};
719 
720 	rdm_api_init_data(source, len, 0xab);
721 	rdm_api_init_data(target, len, 0);
722 
723 	fi_write(ep[0], source, len,
724 		 loc_mr[0], gni_addr[1],
725 		 _REM_ADDR(fi[0], target, target), mr_key[1],
726 		 target);
727 
728 	while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
729 		pthread_yield();
730 
731 	if (ret == -FI_EAVAIL) {
732 		fi_cq_readerr(msg_cq[0], &err_cqe, 0);
733 		dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
734 	}
735 
736 	if (write_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
737 		cr_assert(ret == 1,
738 			  "fi_write failed caps:0x%lx ret:%d",
739 			  fi[0]->caps, ret);
740 	} else {
741 		cr_assert(err_cqe.err == FI_EOPNOTSUPP,
742 			  "fi_write should fail caps:0x%lx err:%d",
743 			  fi[0]->caps, err_cqe.err);
744 	}
745 
746 	fi_read(ep[0], source, len,
747 		loc_mr[0], gni_addr[1],
748 		_REM_ADDR(fi[0], target, target), mr_key[1],
749 		(void *)READ_CTX);
750 
751 	while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
752 		pthread_yield();
753 
754 	if (ret == -FI_EAVAIL) {
755 		fi_cq_readerr(msg_cq[0], &err_cqe, 0);
756 		dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
757 	}
758 
759 	if (read_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
760 		cr_assert(ret == 1,
761 			  "fi_read failed caps:0x%lx rcaps:0x%lx",
762 			  fi[0]->caps, fi[1]->caps);
763 	} else {
764 		cr_assert(err_cqe.err == FI_EOPNOTSUPP,
765 			  "fi_read should fail caps:0x%lx rcaps:0x%lx",
766 			  fi[0]->caps, fi[1]->caps);
767 	}
768 }
769 
__rma_only(uint32_t version,int mr_mode)770 static inline void __rma_only(uint32_t version, int mr_mode)
771 {
772 	hints[0]->caps = FI_RMA;
773 	hints[1]->caps = FI_RMA;
774 	rdm_api_setup_ep(version, mr_mode);
775 	api_write_read(BUF_SZ);
776 }
777 
Test(rdm_api_basic,rma_only)778 Test(rdm_api_basic, rma_only)
779 {
780 	__rma_only(fi_version(), GNIX_MR_BASIC);
781 }
782 
Test(rdm_api_scalable,rma_only)783 Test(rdm_api_scalable, rma_only)
784 {
785 	__rma_only(fi_version(), GNIX_MR_SCALABLE);
786 }
787 
__rma_write_only(uint32_t version,int mr_mode)788 static inline void __rma_write_only(uint32_t version, int mr_mode)
789 {
790 	hints[0]->caps = FI_RMA | FI_WRITE;
791 	hints[1]->caps = FI_RMA | FI_REMOTE_WRITE;
792 	rdm_api_setup_ep(version, mr_mode);
793 	api_write_read(BUF_SZ);
794 }
795 
796 Test(rdm_api_basic, rma_write_only, .disabled = true)
797 {
798 	__rma_write_only(fi_version(), GNIX_MR_BASIC);
799 }
800 
801 Test(rdm_api_scalable, rma_write_only, .disabled = true)
802 {
803 	__rma_write_only(fi_version(), GNIX_MR_SCALABLE);
804 }
805 
__rma_write_no_remote(uint32_t version,int mr_mode)806 static inline void __rma_write_no_remote(uint32_t version, int mr_mode)
807 {
808 	hints[0]->caps = FI_RMA | FI_WRITE;
809 	hints[1]->caps = FI_RMA | FI_WRITE;
810 	rdm_api_setup_ep(version, mr_mode);
811 	api_write_read(BUF_SZ);
812 }
813 
Test(rdm_api_basic,rma_write_no_remote)814 Test(rdm_api_basic, rma_write_no_remote)
815 {
816 	__rma_write_no_remote(fi_version(), GNIX_MR_BASIC);
817 }
818 
Test(rdm_api_scalable,rma_write_no_remote)819 Test(rdm_api_scalable, rma_write_no_remote)
820 {
821 	__rma_write_no_remote(fi_version(), GNIX_MR_SCALABLE);
822 }
823 
__rma_read_only(uint32_t version,int mr_mode)824 static inline void __rma_read_only(uint32_t version, int mr_mode)
825 {
826 	hints[0]->caps = FI_RMA | FI_READ;
827 	hints[1]->caps = FI_RMA | FI_REMOTE_READ;
828 	rdm_api_setup_ep(version, mr_mode);
829 	api_write_read(BUF_SZ);
830 }
831 
832 Test(rdm_api_basic, rma_read_only, .disabled = true)
833 {
834 	__rma_read_only(fi_version(), GNIX_MR_BASIC);
835 }
836 
Test(rdm_api_scalable,rma_read_only)837 Test(rdm_api_scalable, rma_read_only)
838 {
839 	__rma_read_only(fi_version(), GNIX_MR_SCALABLE);
840 }
841 
__rma_read_no_remote(uint32_t version,int mr_mode)842 static inline void __rma_read_no_remote(uint32_t version, int mr_mode)
843 {
844 	hints[0]->caps = FI_RMA | FI_READ;
845 	hints[1]->caps = FI_RMA | FI_READ;
846 	rdm_api_setup_ep(version, mr_mode);
847 	api_write_read(BUF_SZ);
848 }
849 
Test(rdm_api_basic,rma_read_no_remote)850 Test(rdm_api_basic, rma_read_no_remote)
851 {
852 	__rma_read_no_remote(fi_version(), GNIX_MR_BASIC);
853 }
854 
Test(rdm_api_scalable,rma_read_no_remote)855 Test(rdm_api_scalable, rma_read_no_remote)
856 {
857 	__rma_read_no_remote(fi_version(), GNIX_MR_SCALABLE);
858 }
859 
__rma_write_read_w_msg(uint32_t version,int mr_mode)860 static inline void __rma_write_read_w_msg(uint32_t version, int mr_mode)
861 {
862 	hints[0]->caps = FI_MSG;
863 	hints[1]->caps = FI_MSG;
864 	rdm_api_setup_ep(version, mr_mode);
865 	api_write_read(BUF_SZ);
866 }
867 
Test(rdm_api_basic,rma_write_read_w_msg)868 Test(rdm_api_basic, rma_write_read_w_msg)
869 {
870 	__rma_write_read_w_msg(fi_version(), GNIX_MR_BASIC);
871 }
872 
Test(rdm_api_scalable,rma_write_read_w_msg)873 Test(rdm_api_scalable, rma_write_read_w_msg)
874 {
875 	__rma_write_read_w_msg(fi_version(), GNIX_MR_SCALABLE);
876 }
877 
api_do_read_buf(void)878 void api_do_read_buf(void)
879 {
880 	int ret;
881 	int len = 8*1024;
882 	ssize_t sz;
883 	struct fi_cq_tagged_entry cqe;
884 	struct fi_cq_err_entry err_cqe;
885 
886 	rdm_api_init_data(source, BUF_SZ, 0);
887 	rdm_api_init_data(target, BUF_SZ, 0xad);
888 
889 	/* cause a chained transaction */
890 	sz = fi_read(ep[0], source+6, len,
891 			 loc_mr[0], gni_addr[1],
892 			 _REM_ADDR(fi[0], target, target+6), mr_key[1],
893 			 (void *)READ_CTX);
894 	cr_assert_eq(sz, 0);
895 
896 	while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
897 		pthread_yield();
898 
899 	if (ret == -FI_EAVAIL) {
900 		fi_cq_readerr(msg_cq[0], &err_cqe, 0);
901 		dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
902 	}
903 
904 	if (read_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
905 		cr_assert(ret == 1,
906 			  "fi_read failed caps:0x%lx rcaps:0x%lx",
907 			  fi[0]->caps, fi[1]->caps);
908 	} else {
909 		cr_assert(err_cqe.err == FI_EOPNOTSUPP,
910 			  "fi_read should fail caps:0x%lx rcaps:0x%lx",
911 			  fi[0]->caps, fi[1]->caps);
912 	}
913 }
914 
__read_chained(uint32_t version,int mr_mode)915 static inline void __read_chained(uint32_t version, int mr_mode)
916 {
917 	hints[0]->caps = FI_RMA;
918 	hints[1]->caps = FI_RMA;
919 	rdm_api_setup_ep(version, mr_mode);
920 	api_do_read_buf();
921 }
922 
Test(rdm_api_basic,read_chained)923 Test(rdm_api_basic, read_chained)
924 {
925 	__read_chained(fi_version(), GNIX_MR_BASIC);
926 }
927 
Test(rdm_api_scalable,read_chained)928 Test(rdm_api_scalable, read_chained)
929 {
930 	__read_chained(fi_version(), GNIX_MR_SCALABLE);
931 }
932 
__read_chained_remote(uint32_t version,int mr_mode)933 static inline void __read_chained_remote(uint32_t version, int mr_mode)
934 {
935 	hints[0]->caps = FI_RMA | FI_READ;
936 	hints[1]->caps = FI_RMA | FI_REMOTE_READ;
937 	rdm_api_setup_ep(version, mr_mode);
938 	api_do_read_buf();
939 }
940 
941 Test(rdm_api_basic, read_chained_remote, .disabled = true)
942 {
943 	__read_chained_remote(fi_version(), GNIX_MR_BASIC);
944 }
945 
946 Test(rdm_api_scalable, read_chained_remote, .disabled = true)
947 {
948 	__read_chained_remote(fi_version(), GNIX_MR_SCALABLE);
949 }
950 
__read_chained_w_write(uint32_t version,int mr_mode)951 static inline void __read_chained_w_write(uint32_t version, int mr_mode)
952 {
953 	hints[0]->caps = FI_RMA | FI_WRITE;
954 	hints[1]->caps = FI_RMA | FI_REMOTE_READ;
955 	rdm_api_setup_ep(version, mr_mode);
956 	api_do_read_buf();
957 }
958 
959 Test(rdm_api_basic, read_chained_w_write, .disabled = true)
960 {
961 	__read_chained_w_write(fi_version(), GNIX_MR_BASIC);
962 }
963 
Test(rdm_api_scalable,read_chained_w_write)964 Test(rdm_api_scalable, read_chained_w_write)
965 {
966 	__read_chained_w_write(fi_version(), GNIX_MR_SCALABLE);
967 }
968 
__read_chained_no_remote(uint32_t version,int mr_mode)969 static inline void __read_chained_no_remote(uint32_t version, int mr_mode)
970 {
971 	hints[0]->caps = FI_RMA | FI_READ;
972 	hints[1]->caps = FI_RMA | FI_READ;
973 	rdm_api_setup_ep(version, mr_mode);
974 	api_do_read_buf();
975 }
976 
Test(rdm_api_basic,read_chained_no_remote)977 Test(rdm_api_basic, read_chained_no_remote)
978 {
979 	__read_chained_no_remote(fi_version(), GNIX_MR_BASIC);
980 }
981 
Test(rdm_api_scalable,read_chained_no_remote)982 Test(rdm_api_scalable, read_chained_no_remote)
983 {
984 	__read_chained_no_remote(fi_version(), GNIX_MR_SCALABLE);
985 }
986 
987 #define SOURCE_DATA	0xBBBB0000CCCCULL
988 #define TARGET_DATA	0xAAAA0000DDDDULL
989 #define FETCH_SOURCE_DATA	0xACEDACEDULL
990 
do_atomic_write_fetch(void)991 void do_atomic_write_fetch(void)
992 {
993 	int ret;
994 	ssize_t sz;
995 	uint64_t operand;
996 	struct fi_cq_tagged_entry cqe;
997 	struct fi_cq_err_entry err_cqe;
998 
999 	/* u64 */
1000 	*((uint64_t *)source) = SOURCE_DATA;
1001 	*((uint64_t *)target) = TARGET_DATA;
1002 
1003 	sz = fi_atomic(ep[0], source, 1,
1004 			   loc_mr[0], gni_addr[1],
1005 			   _REM_ADDR(fi[0], target, target), mr_key[1],
1006 			   FI_UINT64, FI_ATOMIC_WRITE, target);
1007 	cr_assert_eq(sz, 0);
1008 
1009 	while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
1010 		pthread_yield();
1011 
1012 	if (ret == -FI_EAVAIL) {
1013 		fi_cq_readerr(msg_cq[0], &err_cqe, 0);
1014 		dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
1015 	}
1016 
1017 	if (write_allowed(FI_ATOMIC, fi[0]->caps, fi[1]->caps)) {
1018 		cr_assert(ret == 1,
1019 			  "fi_atomic failed caps:0x%lx rcaps:0x%lx",
1020 			  fi[0]->caps, fi[1]->caps);
1021 	} else {
1022 		cr_assert(err_cqe.err == FI_EOPNOTSUPP,
1023 			  "fi_atomic should fail caps:0x%lx rcaps:0x%lx",
1024 			  fi[0]->caps, fi[1]->caps);
1025 	}
1026 
1027 	/* u64 */
1028 	operand = SOURCE_DATA;
1029 	*((uint64_t *)source) = FETCH_SOURCE_DATA;
1030 	*((uint64_t *)target) = TARGET_DATA;
1031 	sz = fi_fetch_atomic(ep[0], &operand, 1, NULL,
1032 				 source, loc_mr[0], gni_addr[1],
1033 				 _REM_ADDR(fi[0], target, target),
1034 				 mr_key[1], FI_UINT64, FI_ATOMIC_READ, target);
1035 	cr_assert_eq(sz, 0);
1036 
1037 	while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
1038 		pthread_yield();
1039 
1040 	if (ret == -FI_EAVAIL) {
1041 		fi_cq_readerr(msg_cq[0], &err_cqe, 0);
1042 		dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
1043 		}
1044 
1045 	if (read_allowed(FI_ATOMIC, fi[0]->caps, fi[1]->caps)) {
1046 		cr_assert(ret == 1,
1047 			  "fi_fetch_atomic failed caps:0x%lx rcaps:0x%lx",
1048 			  fi[0]->caps, fi[1]->caps);
1049 	} else {
1050 		cr_assert(err_cqe.err == FI_EOPNOTSUPP,
1051 			  "fi_fetch_atomic should fail caps:0x%lx rcaps:0x%lx",
1052 			  fi[0]->caps, fi[1]->caps);
1053 	}
1054 }
1055 
__amo_write_read(uint32_t version,int mr_mode)1056 static inline void __amo_write_read(uint32_t version, int mr_mode)
1057 {
1058 	hints[0]->caps = FI_ATOMIC;
1059 	hints[1]->caps = FI_ATOMIC;
1060 	rdm_api_setup_ep(version, mr_mode);
1061 	do_atomic_write_fetch();
1062 }
1063 
Test(rdm_api_basic,amo_write_read)1064 Test(rdm_api_basic, amo_write_read)
1065 {
1066 	__amo_write_read(fi_version(), GNIX_MR_BASIC);
1067 }
1068 
Test(rdm_api_scalable,amo_write_read)1069 Test(rdm_api_scalable, amo_write_read)
1070 {
1071 	__amo_write_read(fi_version(), GNIX_MR_SCALABLE);
1072 }
1073 
__amo_write_only(uint32_t version,int mr_mode)1074 static inline void __amo_write_only(uint32_t version, int mr_mode)
1075 {
1076 	hints[0]->caps = FI_ATOMIC | FI_WRITE;
1077 	hints[1]->caps = FI_ATOMIC | FI_REMOTE_WRITE;
1078 	rdm_api_setup_ep(version, mr_mode);
1079 	do_atomic_write_fetch();
1080 }
1081 
1082 Test(rdm_api_basic, amo_write_only, .disabled = true)
1083 {
1084 	__amo_write_only(fi_version(), GNIX_MR_BASIC);
1085 }
1086 
Test(rdm_api_scalable,amo_write_only)1087 Test(rdm_api_scalable, amo_write_only)
1088 {
1089 	__amo_write_only(fi_version(), GNIX_MR_SCALABLE);
1090 }
1091 
__amo_write_no_remote(uint32_t version,int mr_mode)1092 static inline void __amo_write_no_remote(uint32_t version, int mr_mode)
1093 {
1094 	hints[0]->caps = FI_ATOMIC | FI_WRITE;
1095 	hints[1]->caps = FI_ATOMIC | FI_WRITE;
1096 	rdm_api_setup_ep(version, mr_mode);
1097 	do_atomic_write_fetch();
1098 }
1099 
Test(rdm_api_basic,amo_write_no_remote)1100 Test(rdm_api_basic, amo_write_no_remote)
1101 {
1102 	__amo_write_no_remote(fi_version(), GNIX_MR_BASIC);
1103 }
1104 
Test(rdm_api_scalable,amo_write_no_remote)1105 Test(rdm_api_scalable, amo_write_no_remote)
1106 {
1107 	__amo_write_no_remote(fi_version(), GNIX_MR_SCALABLE);
1108 }
1109 
__amo_read_only(uint32_t version,int mr_mode)1110 static inline void __amo_read_only(uint32_t version, int mr_mode)
1111 {
1112 	hints[0]->caps = FI_ATOMIC | FI_READ;
1113 	hints[1]->caps = FI_ATOMIC | FI_REMOTE_READ;
1114 	rdm_api_setup_ep(version, mr_mode);
1115 	do_atomic_write_fetch();
1116 }
1117 
1118 Test(rdm_api_basic, amo_read_only, .disabled = true)
1119 {
1120 	__amo_read_only(fi_version(), GNIX_MR_BASIC);
1121 }
1122 
Test(rdm_api_scalable,amo_read_only)1123 Test(rdm_api_scalable, amo_read_only)
1124 {
1125 	__amo_read_only(fi_version(), GNIX_MR_SCALABLE);
1126 }
1127 
__amo_read_no_remote(uint32_t version,int mr_mode)1128 static inline void __amo_read_no_remote(uint32_t version, int mr_mode)
1129 {
1130 	hints[0]->caps = FI_ATOMIC | FI_READ;
1131 	hints[1]->caps = FI_ATOMIC | FI_READ;
1132 	rdm_api_setup_ep(version, mr_mode);
1133 	do_atomic_write_fetch();
1134 }
1135 
Test(rdm_api_basic,amo_read_no_remote)1136 Test(rdm_api_basic, amo_read_no_remote)
1137 {
1138 	__amo_read_no_remote(fi_version(), GNIX_MR_BASIC);
1139 }
1140 
Test(rdm_api_scalable,amo_read_no_remote)1141 Test(rdm_api_scalable, amo_read_no_remote)
1142 {
1143 	__amo_read_no_remote(fi_version(), GNIX_MR_SCALABLE);
1144 }
1145 
__amo_write_read_w_msg(uint32_t version,int mr_mode)1146 static inline void __amo_write_read_w_msg(uint32_t version, int mr_mode)
1147 {
1148 	hints[0]->caps = FI_MSG;
1149 	hints[1]->caps = FI_MSG;
1150 	rdm_api_setup_ep(version, mr_mode);
1151 	api_write_read(BUF_SZ);
1152 }
1153 
Test(rdm_api_basic,amo_write_read_w_msg)1154 Test(rdm_api_basic, amo_write_read_w_msg)
1155 {
1156 	__amo_write_read_w_msg(fi_version(), GNIX_MR_BASIC);
1157 }
1158 
Test(rdm_api_scalable,amo_write_read_w_msg)1159 Test(rdm_api_scalable, amo_write_read_w_msg)
1160 {
1161 	__amo_write_read_w_msg(fi_version(), GNIX_MR_SCALABLE);
1162 }
1163 
1164 TestSuite(api, .init = api_setup, .fini = api_teardown, .disabled = false);
1165 
Test(api,getinfo_w_null_hints)1166 Test(api, getinfo_w_null_hints)
1167 {
1168 	int ret;
1169 
1170 	ret = fi_getinfo(fi_version(), NULL, 0, 0, NULL, &fi[0]);
1171 	cr_assert(ret == FI_SUCCESS, "fi_getinfo returned: %s",
1172 		  fi_strerror(-ret));
1173 }
1174