/* * Copyright (c) 2005-2009 Intel Corporation. All rights reserved. * * This software is available to you under the OpenIB.org BSD license * below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include #include #include #include static const char *server = "0.0.0.0"; static const char *port = "7471"; static struct rdma_cm_id *listen_id, *id; static struct ibv_mr *mr, *send_mr; static int send_flags; static uint8_t send_msg[16]; static uint8_t recv_msg[16]; static int run(void) { struct rdma_addrinfo hints, *res; struct ibv_qp_init_attr init_attr; struct ibv_qp_attr qp_attr; struct ibv_wc wc; int ret; memset(&hints, 0, sizeof hints); hints.ai_flags = RAI_PASSIVE; hints.ai_port_space = RDMA_PS_TCP; ret = rdma_getaddrinfo(server, port, &hints, &res); if (ret) { printf("rdma_getaddrinfo: %s\n", gai_strerror(ret)); return ret; } memset(&init_attr, 0, sizeof init_attr); init_attr.cap.max_send_wr = init_attr.cap.max_recv_wr = 1; init_attr.cap.max_send_sge = init_attr.cap.max_recv_sge = 1; init_attr.cap.max_inline_data = 16; init_attr.sq_sig_all = 1; ret = rdma_create_ep(&listen_id, res, NULL, &init_attr); if (ret) { perror("rdma_create_ep"); goto out_free_addrinfo; } ret = rdma_listen(listen_id, 0); if (ret) { perror("rdma_listen"); goto out_destroy_listen_ep; } ret = rdma_get_request(listen_id, &id); if (ret) { perror("rdma_get_request"); goto out_destroy_listen_ep; } memset(&qp_attr, 0, sizeof qp_attr); memset(&init_attr, 0, sizeof init_attr); ret = ibv_query_qp(id->qp, &qp_attr, IBV_QP_CAP, &init_attr); if (ret) { perror("ibv_query_qp"); goto out_destroy_accept_ep; } if (init_attr.cap.max_inline_data >= 16) send_flags = IBV_SEND_INLINE; else printf("rdma_server: device doesn't support IBV_SEND_INLINE, " "using sge sends\n"); mr = rdma_reg_msgs(id, recv_msg, 16); if (!mr) { ret = -1; perror("rdma_reg_msgs for recv_msg"); goto out_destroy_accept_ep; } if ((send_flags & IBV_SEND_INLINE) == 0) { send_mr = rdma_reg_msgs(id, send_msg, 16); if (!send_mr) { ret = -1; perror("rdma_reg_msgs for send_msg"); goto out_dereg_recv; } } ret = rdma_post_recv(id, NULL, recv_msg, 16, mr); if (ret) { perror("rdma_post_recv"); goto out_dereg_send; } ret = rdma_accept(id, NULL); if (ret) { perror("rdma_accept"); goto out_dereg_send; } while ((ret = rdma_get_recv_comp(id, &wc)) == 0); if (ret < 0) { perror("rdma_get_recv_comp"); goto out_disconnect; } ret = rdma_post_send(id, NULL, send_msg, 16, send_mr, send_flags); if (ret) { perror("rdma_post_send"); goto out_disconnect; } while ((ret = rdma_get_send_comp(id, &wc)) == 0); if (ret < 0) perror("rdma_get_send_comp"); else ret = 0; out_disconnect: rdma_disconnect(id); out_dereg_send: if ((send_flags & IBV_SEND_INLINE) == 0) rdma_dereg_mr(send_mr); out_dereg_recv: rdma_dereg_mr(mr); out_destroy_accept_ep: rdma_destroy_ep(id); out_destroy_listen_ep: rdma_destroy_ep(listen_id); out_free_addrinfo: rdma_freeaddrinfo(res); return ret; } int main(int argc, char **argv) { int op, ret; while ((op = getopt(argc, argv, "s:p:")) != -1) { switch (op) { case 's': server = optarg; break; case 'p': port = optarg; break; default: printf("usage: %s\n", argv[0]); printf("\t[-s server_address]\n"); printf("\t[-p port_number]\n"); exit(1); } } printf("rdma_server: start\n"); ret = run(); printf("rdma_server: end %d\n", ret); return ret; }