1 /* 2 * Copyright (c) 2010-2014 Intel Corporation. All rights reserved. 3 * 4 * This software is available to you under the OpenIB.org BSD license 5 * below: 6 * 7 * Redistribution and use in source and binary forms, with or 8 * without modification, are permitted provided that the following 9 * conditions are met: 10 * 11 * - Redistributions of source code must retain the above 12 * copyright notice, this list of conditions and the following 13 * disclaimer. 14 * 15 * - Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials 18 * provided with the distribution. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV 23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 * SOFTWARE. 28 */ 29 30 #include <endian.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <netdb.h> 35 #include <errno.h> 36 #include <getopt.h> 37 #include <ctype.h> 38 #include <rdma/rdma_cma.h> 39 #include <rdma/rdma_verbs.h> 40 41 static const char *server = "127.0.0.1"; 42 static char port[6] = "7471"; 43 44 static struct rdma_cm_id *id; 45 static struct ibv_mr *mr; 46 static struct rdma_addrinfo hints; 47 48 static uint8_t send_msg[16]; 49 static uint32_t srqn; 50 51 static int post_send(void) 52 { 53 struct ibv_send_wr wr, *bad; 54 struct ibv_sge sge; 55 int ret; 56 57 sge.addr = (uint64_t) (uintptr_t) send_msg; 58 sge.length = (uint32_t) sizeof send_msg; 59 sge.lkey = 0; 60 wr.wr_id = (uintptr_t) NULL; 61 wr.next = NULL; 62 wr.sg_list = &sge; 63 wr.num_sge = 1; 64 wr.opcode = IBV_WR_SEND; 65 wr.send_flags = IBV_SEND_INLINE; 66 if (hints.ai_qp_type == IBV_QPT_XRC_SEND) 67 wr.qp_type.xrc.remote_srqn = srqn; 68 69 ret = ibv_post_send(id->qp, &wr, &bad); 70 if (ret) 71 perror("rdma_post_send"); 72 73 return ret; 74 } 75 76 static int test(void) 77 { 78 struct rdma_addrinfo *res; 79 struct ibv_qp_init_attr attr; 80 struct ibv_wc wc; 81 int ret; 82 83 ret = rdma_getaddrinfo(server, port, &hints, &res); 84 if (ret) { 85 printf("rdma_getaddrinfo: %s\n", gai_strerror(ret)); 86 return ret; 87 } 88 89 memset(&attr, 0, sizeof attr); 90 attr.cap.max_send_wr = attr.cap.max_recv_wr = 1; 91 attr.cap.max_send_sge = attr.cap.max_recv_sge = 1; 92 attr.sq_sig_all = 1; 93 ret = rdma_create_ep(&id, res, NULL, &attr); 94 rdma_freeaddrinfo(res); 95 if (ret) { 96 perror("rdma_create_ep"); 97 return ret; 98 } 99 100 mr = rdma_reg_msgs(id, send_msg, sizeof send_msg); 101 if (!mr) { 102 perror("rdma_reg_msgs"); 103 return ret; 104 } 105 106 ret = rdma_connect(id, NULL); 107 if (ret) { 108 perror("rdma_connect"); 109 return ret; 110 } 111 112 if (hints.ai_qp_type == IBV_QPT_XRC_SEND) 113 srqn = be32toh(*(__be32 *) id->event->param.conn.private_data); 114 115 ret = post_send(); 116 if (ret) { 117 perror("post_send"); 118 return ret; 119 } 120 121 ret = rdma_get_send_comp(id, &wc); 122 if (ret <= 0) { 123 perror("rdma_get_recv_comp"); 124 return ret; 125 } 126 127 rdma_disconnect(id); 128 rdma_dereg_mr(mr); 129 rdma_destroy_ep(id); 130 return 0; 131 } 132 133 int main(int argc, char **argv) 134 { 135 int op, ret; 136 137 hints.ai_port_space = RDMA_PS_TCP; 138 hints.ai_qp_type = IBV_QPT_RC; 139 140 while ((op = getopt(argc, argv, "s:p:c:")) != -1) { 141 switch (op) { 142 case 's': 143 server = optarg; 144 break; 145 case 'p': 146 strncpy(port, optarg, sizeof port - 1); 147 break; 148 case 'c': 149 switch (tolower(optarg[0])) { 150 case 'r': 151 break; 152 case 'x': 153 hints.ai_port_space = RDMA_PS_IB; 154 hints.ai_qp_type = IBV_QPT_XRC_SEND; 155 break; 156 default: 157 goto err; 158 } 159 break; 160 default: 161 goto err; 162 } 163 } 164 165 printf("%s: start\n", argv[0]); 166 ret = test(); 167 printf("%s: end %d\n", argv[0], ret); 168 return ret; 169 170 err: 171 printf("usage: %s\n", argv[0]); 172 printf("\t[-s server]\n"); 173 printf("\t[-p port_number]\n"); 174 printf("\t[-c communication type]\n"); 175 printf("\t r - RC: reliable-connected (default)\n"); 176 printf("\t x - XRC: extended-reliable-connected\n"); 177 exit(1); 178 } 179