| /* |
| * Copyright (c) 2005-2014 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 <endian.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <getopt.h> |
| #include <netdb.h> |
| #include <ctype.h> |
| #include <rdma/rdma_cma.h> |
| #include <rdma/rdma_verbs.h> |
| |
| static const char *port = "7471"; |
| |
| static struct rdma_cm_id *listen_id, *id; |
| static struct ibv_mr *mr; |
| static struct rdma_addrinfo hints; |
| |
| static uint8_t recv_msg[16]; |
| static __be32 srqn; |
| |
| static int create_srq(void) |
| { |
| struct ibv_srq_init_attr attr; |
| int ret; |
| uint32_t tmp_srqn; |
| |
| attr.attr.max_wr = 1; |
| attr.attr.max_sge = 1; |
| attr.attr.srq_limit = 0; |
| attr.srq_context = id; |
| |
| ret = rdma_create_srq(id, NULL, &attr); |
| if (ret) |
| perror("rdma_create_srq:"); |
| |
| if (id->srq) { |
| ibv_get_srq_num(id->srq, &tmp_srqn); |
| srqn = htobe32(tmp_srqn); |
| } |
| return ret; |
| } |
| |
| static int test(void) |
| { |
| struct rdma_addrinfo *res; |
| struct ibv_qp_init_attr attr; |
| struct rdma_conn_param param; |
| struct ibv_wc wc; |
| int ret; |
| |
| ret = rdma_getaddrinfo(NULL, port, &hints, &res); |
| if (ret) { |
| printf("rdma_getaddrinfo: %s\n", gai_strerror(ret)); |
| return ret; |
| } |
| |
| memset(&attr, 0, sizeof attr); |
| attr.cap.max_recv_wr = 1; |
| attr.cap.max_recv_sge = 1; |
| if (hints.ai_qp_type != IBV_QPT_XRC_RECV) { |
| attr.cap.max_send_wr = 1; |
| attr.cap.max_send_sge = 1; |
| } |
| ret = rdma_create_ep(&listen_id, res, NULL, &attr); |
| rdma_freeaddrinfo(res); |
| if (ret) { |
| perror("rdma_create_ep"); |
| return ret; |
| } |
| |
| ret = rdma_listen(listen_id, 0); |
| if (ret) { |
| perror("rdma_listen"); |
| return ret; |
| } |
| |
| ret = rdma_get_request(listen_id, &id); |
| if (ret) { |
| perror("rdma_get_request"); |
| return ret; |
| } |
| |
| if (hints.ai_qp_type == IBV_QPT_XRC_RECV) { |
| ret = create_srq(); |
| if (ret) |
| return ret; |
| } |
| |
| mr = rdma_reg_msgs(id, recv_msg, sizeof recv_msg); |
| if (!mr) { |
| perror("rdma_reg_msgs"); |
| return ret; |
| } |
| |
| ret = rdma_post_recv(id, NULL, recv_msg, sizeof recv_msg, mr); |
| if (ret) { |
| perror("rdma_post_recv"); |
| return ret; |
| } |
| |
| memset(¶m, 0, sizeof param); |
| param.private_data = &srqn; |
| param.private_data_len = sizeof srqn; |
| ret = rdma_accept(id, ¶m); |
| if (ret) { |
| perror("rdma_accept"); |
| return ret; |
| } |
| |
| ret = rdma_get_recv_comp(id, &wc); |
| if (ret <= 0) { |
| perror("rdma_get_recv_comp"); |
| return ret; |
| } |
| |
| rdma_disconnect(id); |
| rdma_dereg_mr(mr); |
| rdma_destroy_ep(id); |
| rdma_destroy_ep(listen_id); |
| return 0; |
| } |
| |
| int main(int argc, char **argv) |
| { |
| int op, ret; |
| |
| hints.ai_flags = RAI_PASSIVE; |
| hints.ai_port_space = RDMA_PS_TCP; |
| hints.ai_qp_type = IBV_QPT_RC; |
| |
| while ((op = getopt(argc, argv, "p:c:")) != -1) { |
| switch (op) { |
| case 'p': |
| port = optarg; |
| break; |
| case 'c': |
| switch (tolower(optarg[0])) { |
| case 'r': |
| break; |
| case 'x': |
| hints.ai_port_space = RDMA_PS_IB; |
| hints.ai_qp_type = IBV_QPT_XRC_RECV; |
| break; |
| default: |
| goto err; |
| } |
| break; |
| default: |
| goto err; |
| } |
| } |
| |
| printf("%s: start\n", argv[0]); |
| ret = test(); |
| printf("%s: end %d\n", argv[0], ret); |
| return ret; |
| |
| err: |
| printf("usage: %s\n", argv[0]); |
| printf("\t[-p port_number]\n"); |
| printf("\t[-c communication type]\n"); |
| printf("\t r - RC: reliable-connected (default)\n"); |
| printf("\t x - XRC: extended-reliable-connected\n"); |
| exit(1); |
| } |