1 /* 2 * Copyright (c) 2010 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 <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <netdb.h> 34 #include <errno.h> 35 #include <getopt.h> 36 #include <rdma/rdma_cma.h> 37 #include <rdma/rdma_verbs.h> 38 39 static const char *server = "127.0.0.1"; 40 static const char *port = "7471"; 41 42 static struct rdma_cm_id *id; 43 static struct ibv_mr *mr, *send_mr; 44 static int send_flags; 45 static uint8_t send_msg[16]; 46 static uint8_t recv_msg[16]; 47 48 static int run(void) 49 { 50 struct rdma_addrinfo hints, *res; 51 struct ibv_qp_init_attr attr; 52 struct ibv_wc wc; 53 int ret; 54 55 memset(&hints, 0, sizeof hints); 56 hints.ai_port_space = RDMA_PS_TCP; 57 ret = rdma_getaddrinfo(server, port, &hints, &res); 58 if (ret) { 59 printf("rdma_getaddrinfo: %s\n", gai_strerror(ret)); 60 goto out; 61 } 62 63 memset(&attr, 0, sizeof attr); 64 attr.cap.max_send_wr = attr.cap.max_recv_wr = 1; 65 attr.cap.max_send_sge = attr.cap.max_recv_sge = 1; 66 attr.cap.max_inline_data = 16; 67 attr.qp_context = id; 68 attr.sq_sig_all = 1; 69 ret = rdma_create_ep(&id, res, NULL, &attr); 70 // Check to see if we got inline data allowed or not 71 if (attr.cap.max_inline_data >= 16) 72 send_flags = IBV_SEND_INLINE; 73 else 74 printf("rdma_client: device doesn't support IBV_SEND_INLINE, " 75 "using sge sends\n"); 76 77 if (ret) { 78 perror("rdma_create_ep"); 79 goto out_free_addrinfo; 80 } 81 82 mr = rdma_reg_msgs(id, recv_msg, 16); 83 if (!mr) { 84 perror("rdma_reg_msgs for recv_msg"); 85 ret = -1; 86 goto out_destroy_ep; 87 } 88 if ((send_flags & IBV_SEND_INLINE) == 0) { 89 send_mr = rdma_reg_msgs(id, send_msg, 16); 90 if (!send_mr) { 91 perror("rdma_reg_msgs for send_msg"); 92 ret = -1; 93 goto out_dereg_recv; 94 } 95 } 96 97 ret = rdma_post_recv(id, NULL, recv_msg, 16, mr); 98 if (ret) { 99 perror("rdma_post_recv"); 100 goto out_dereg_send; 101 } 102 103 ret = rdma_connect(id, NULL); 104 if (ret) { 105 perror("rdma_connect"); 106 goto out_dereg_send; 107 } 108 109 ret = rdma_post_send(id, NULL, send_msg, 16, send_mr, send_flags); 110 if (ret) { 111 perror("rdma_post_send"); 112 goto out_disconnect; 113 } 114 115 while ((ret = rdma_get_send_comp(id, &wc)) == 0); 116 if (ret < 0) { 117 perror("rdma_get_send_comp"); 118 goto out_disconnect; 119 } 120 121 while ((ret = rdma_get_recv_comp(id, &wc)) == 0); 122 if (ret < 0) 123 perror("rdma_get_recv_comp"); 124 else 125 ret = 0; 126 127 out_disconnect: 128 rdma_disconnect(id); 129 out_dereg_send: 130 if ((send_flags & IBV_SEND_INLINE) == 0) 131 rdma_dereg_mr(send_mr); 132 out_dereg_recv: 133 rdma_dereg_mr(mr); 134 out_destroy_ep: 135 rdma_destroy_ep(id); 136 out_free_addrinfo: 137 rdma_freeaddrinfo(res); 138 out: 139 return ret; 140 } 141 142 int main(int argc, char **argv) 143 { 144 int op, ret; 145 146 while ((op = getopt(argc, argv, "s:p:")) != -1) { 147 switch (op) { 148 case 's': 149 server = optarg; 150 break; 151 case 'p': 152 port = optarg; 153 break; 154 default: 155 printf("usage: %s\n", argv[0]); 156 printf("\t[-s server_address]\n"); 157 printf("\t[-p port_number]\n"); 158 exit(1); 159 } 160 } 161 162 printf("rdma_client: start\n"); 163 ret = run(); 164 printf("rdma_client: end %d\n", ret); 165 return ret; 166 } 167