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