1 /* 2 * Copyright (c) 2005-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 <errno.h> 35 #include <getopt.h> 36 #include <netdb.h> 37 #include <ctype.h> 38 #include <rdma/rdma_cma.h> 39 #include <rdma/rdma_verbs.h> 40 41 static const char *port = "7471"; 42 43 static struct rdma_cm_id *listen_id, *id; 44 static struct ibv_mr *mr; 45 static struct rdma_addrinfo hints; 46 47 static uint8_t recv_msg[16]; 48 static __be32 srqn; 49 50 static int create_srq(void) 51 { 52 struct ibv_srq_init_attr attr; 53 int ret; 54 uint32_t tmp_srqn; 55 56 attr.attr.max_wr = 1; 57 attr.attr.max_sge = 1; 58 attr.attr.srq_limit = 0; 59 attr.srq_context = id; 60 61 ret = rdma_create_srq(id, NULL, &attr); 62 if (ret) 63 perror("rdma_create_srq:"); 64 65 if (id->srq) { 66 ibv_get_srq_num(id->srq, &tmp_srqn); 67 srqn = htobe32(tmp_srqn); 68 } 69 return ret; 70 } 71 72 static int test(void) 73 { 74 struct rdma_addrinfo *res; 75 struct ibv_qp_init_attr attr; 76 struct rdma_conn_param param; 77 struct ibv_wc wc; 78 int ret; 79 80 ret = rdma_getaddrinfo(NULL, port, &hints, &res); 81 if (ret) { 82 printf("rdma_getaddrinfo: %s\n", gai_strerror(ret)); 83 return ret; 84 } 85 86 memset(&attr, 0, sizeof attr); 87 attr.cap.max_send_wr = attr.cap.max_recv_wr = 1; 88 attr.cap.max_send_sge = attr.cap.max_recv_sge = 1; 89 ret = rdma_create_ep(&listen_id, res, NULL, &attr); 90 rdma_freeaddrinfo(res); 91 if (ret) { 92 perror("rdma_create_ep"); 93 return ret; 94 } 95 96 ret = rdma_listen(listen_id, 0); 97 if (ret) { 98 perror("rdma_listen"); 99 return ret; 100 } 101 102 ret = rdma_get_request(listen_id, &id); 103 if (ret) { 104 perror("rdma_get_request"); 105 return ret; 106 } 107 108 if (hints.ai_qp_type == IBV_QPT_XRC_RECV) { 109 ret = create_srq(); 110 if (ret) 111 return ret; 112 } 113 114 mr = rdma_reg_msgs(id, recv_msg, sizeof recv_msg); 115 if (!mr) { 116 perror("rdma_reg_msgs"); 117 return ret; 118 } 119 120 ret = rdma_post_recv(id, NULL, recv_msg, sizeof recv_msg, mr); 121 if (ret) { 122 perror("rdma_post_recv"); 123 return ret; 124 } 125 126 memset(¶m, 0, sizeof param); 127 param.private_data = &srqn; 128 param.private_data_len = sizeof srqn; 129 ret = rdma_accept(id, ¶m); 130 if (ret) { 131 perror("rdma_accept"); 132 return ret; 133 } 134 135 ret = rdma_get_recv_comp(id, &wc); 136 if (ret <= 0) { 137 perror("rdma_get_recv_comp"); 138 return ret; 139 } 140 141 rdma_disconnect(id); 142 rdma_dereg_mr(mr); 143 rdma_destroy_ep(id); 144 rdma_destroy_ep(listen_id); 145 return 0; 146 } 147 148 int main(int argc, char **argv) 149 { 150 int op, ret; 151 152 hints.ai_flags = RAI_PASSIVE; 153 hints.ai_port_space = RDMA_PS_TCP; 154 hints.ai_qp_type = IBV_QPT_RC; 155 156 while ((op = getopt(argc, argv, "p:c:")) != -1) { 157 switch (op) { 158 case 'p': 159 port = optarg; 160 break; 161 case 'c': 162 switch (tolower(optarg[0])) { 163 case 'r': 164 break; 165 case 'x': 166 hints.ai_port_space = RDMA_PS_IB; 167 hints.ai_qp_type = IBV_QPT_XRC_RECV; 168 break; 169 default: 170 goto err; 171 } 172 break; 173 default: 174 goto err; 175 } 176 } 177 178 printf("%s: start\n", argv[0]); 179 ret = test(); 180 printf("%s: end %d\n", argv[0], ret); 181 return ret; 182 183 err: 184 printf("usage: %s\n", argv[0]); 185 printf("\t[-p port_number]\n"); 186 printf("\t[-c communication type]\n"); 187 printf("\t r - RC: reliable-connected (default)\n"); 188 printf("\t x - XRC: extended-reliable-connected\n"); 189 exit(1); 190 } 191