Changeset View
Changeset View
Standalone View
Standalone View
contrib/ofed/libibverbs/examples/ud_pingpong.c
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#include "pingpong.h" | #include "pingpong.h" | ||||
enum { | enum { | ||||
PINGPONG_RECV_WRID = 1, | PINGPONG_RECV_WRID = 1, | ||||
PINGPONG_SEND_WRID = 2, | PINGPONG_SEND_WRID = 2, | ||||
}; | }; | ||||
static int page_size; | static int page_size; | ||||
static int family = AF_INET; | |||||
struct pingpong_context { | struct pingpong_context { | ||||
struct ibv_context *context; | struct ibv_context *context; | ||||
struct ibv_comp_channel *channel; | struct ibv_comp_channel *channel; | ||||
struct ibv_pd *pd; | struct ibv_pd *pd; | ||||
struct ibv_mr *mr; | struct ibv_mr *mr; | ||||
struct ibv_cq *cq; | struct ibv_cq *cq; | ||||
struct ibv_qp *qp; | struct ibv_qp *qp; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, | ||||
return 0; | return 0; | ||||
} | } | ||||
static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port, | static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port, | ||||
const struct pingpong_dest *my_dest) | const struct pingpong_dest *my_dest) | ||||
{ | { | ||||
struct addrinfo *res, *t; | struct addrinfo *res, *t; | ||||
struct addrinfo hints = { | struct addrinfo hints = { | ||||
.ai_family = AF_INET, | .ai_family = family, | ||||
.ai_socktype = SOCK_STREAM | .ai_socktype = SOCK_STREAM | ||||
}; | }; | ||||
char *service; | char *service; | ||||
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; | char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; | ||||
int n; | int n; | ||||
int sockfd = -1; | int sockfd = -1; | ||||
struct pingpong_dest *rem_dest = NULL; | struct pingpong_dest *rem_dest = NULL; | ||||
char gid[33]; | char gid[33]; | ||||
if (asprintf(&service, "%d", port) < 0) | if (asprintf(&service, "%d", port) < 0) | ||||
return NULL; | return NULL; | ||||
n = getaddrinfo(servername, service, &hints, &res); | n = getaddrinfo(servername, service, &hints, &res); | ||||
if (n < 0) { | if (n < 0) { | ||||
fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port); | fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port); | ||||
free(service); | free(service); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
for (t = res; t; t = t->ai_next) { | for (t = res; t; t = t->ai_next) { | ||||
if (t->ai_family != family) | |||||
continue; | |||||
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); | sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); | ||||
if (sockfd >= 0) { | if (sockfd >= 0) { | ||||
if (!connect(sockfd, t->ai_addr, t->ai_addrlen)) | if (!connect(sockfd, t->ai_addr, t->ai_addrlen)) | ||||
break; | break; | ||||
close(sockfd); | close(sockfd); | ||||
sockfd = -1; | sockfd = -1; | ||||
} | } | ||||
} | } | ||||
freeaddrinfo(res); | freeaddrinfo(res); | ||||
free(service); | free(service); | ||||
if (sockfd < 0) { | if (sockfd < 0) { | ||||
fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port); | fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
gid_to_wire_gid(&my_dest->gid, gid); | gid_to_wire_gid(&my_dest->gid, gid); | ||||
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid); | sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, | ||||
my_dest->psn, gid); | |||||
if (write(sockfd, msg, sizeof msg) != sizeof msg) { | if (write(sockfd, msg, sizeof msg) != sizeof msg) { | ||||
fprintf(stderr, "Couldn't send local address\n"); | fprintf(stderr, "Couldn't send local address\n"); | ||||
goto out; | goto out; | ||||
} | } | ||||
if (read(sockfd, msg, sizeof msg) != sizeof msg) { | if (recv(sockfd, msg, sizeof(msg), MSG_WAITALL) != sizeof(msg)) { | ||||
perror("client read"); | perror("client read"); | ||||
fprintf(stderr, "Couldn't read remote address\n"); | fprintf(stderr, "Couldn't read remote address\n"); | ||||
goto out; | goto out; | ||||
} | } | ||||
write(sockfd, "done", sizeof "done"); | if (write(sockfd, "done", sizeof("done")) != sizeof("done")) { | ||||
fprintf(stderr, "Couldn't send \"done\" msg\n"); | |||||
goto out; | |||||
} | |||||
rem_dest = malloc(sizeof *rem_dest); | rem_dest = malloc(sizeof *rem_dest); | ||||
if (!rem_dest) | if (!rem_dest) | ||||
goto out; | goto out; | ||||
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); | sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, | ||||
&rem_dest->psn, gid); | |||||
wire_gid_to_gid(gid, &rem_dest->gid); | wire_gid_to_gid(gid, &rem_dest->gid); | ||||
out: | out: | ||||
close(sockfd); | close(sockfd); | ||||
return rem_dest; | return rem_dest; | ||||
} | } | ||||
static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, | static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, | ||||
int ib_port, int port, int sl, | int ib_port, int port, int sl, | ||||
const struct pingpong_dest *my_dest, | const struct pingpong_dest *my_dest, | ||||
int sgid_idx) | int sgid_idx) | ||||
{ | { | ||||
struct addrinfo *res, *t; | struct addrinfo *res, *t; | ||||
struct addrinfo hints = { | struct addrinfo hints = { | ||||
.ai_flags = AI_PASSIVE, | .ai_flags = AI_PASSIVE, | ||||
.ai_family = AF_INET, | .ai_family = family, | ||||
.ai_socktype = SOCK_STREAM | .ai_socktype = SOCK_STREAM | ||||
}; | }; | ||||
char *service; | char *service; | ||||
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; | char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; | ||||
int n; | int n; | ||||
int sockfd = -1, connfd; | int sockfd = -1, connfd; | ||||
struct pingpong_dest *rem_dest = NULL; | struct pingpong_dest *rem_dest = NULL; | ||||
char gid[33]; | char gid[33]; | ||||
if (asprintf(&service, "%d", port) < 0) | if (asprintf(&service, "%d", port) < 0) | ||||
return NULL; | return NULL; | ||||
n = getaddrinfo(NULL, service, &hints, &res); | n = getaddrinfo(NULL, service, &hints, &res); | ||||
if (n < 0) { | if (n < 0) { | ||||
fprintf(stderr, "%s for port %d\n", gai_strerror(n), port); | fprintf(stderr, "%s for port %d\n", gai_strerror(n), port); | ||||
free(service); | free(service); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
for (t = res; t; t = t->ai_next) { | for (t = res; t; t = t->ai_next) { | ||||
if (t->ai_family != family) | |||||
continue; | |||||
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); | sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); | ||||
if (sockfd >= 0) { | if (sockfd >= 0) { | ||||
n = 1; | n = 1; | ||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n); | setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n); | ||||
if (!bind(sockfd, t->ai_addr, t->ai_addrlen)) | if (!bind(sockfd, t->ai_addr, t->ai_addrlen)) | ||||
break; | break; | ||||
Show All 13 Lines | static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, | ||||
listen(sockfd, 1); | listen(sockfd, 1); | ||||
connfd = accept(sockfd, NULL, 0); | connfd = accept(sockfd, NULL, 0); | ||||
close(sockfd); | close(sockfd); | ||||
if (connfd < 0) { | if (connfd < 0) { | ||||
fprintf(stderr, "accept() failed\n"); | fprintf(stderr, "accept() failed\n"); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
n = read(connfd, msg, sizeof msg); | n = recv(connfd, msg, sizeof(msg), MSG_WAITALL); | ||||
if (n != sizeof msg) { | if (n != sizeof msg) { | ||||
perror("server read"); | perror("server read"); | ||||
fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg); | fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg); | ||||
goto out; | goto out; | ||||
} | } | ||||
rem_dest = malloc(sizeof *rem_dest); | rem_dest = malloc(sizeof *rem_dest); | ||||
if (!rem_dest) | if (!rem_dest) | ||||
goto out; | goto out; | ||||
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); | sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, | ||||
&rem_dest->psn, gid); | |||||
wire_gid_to_gid(gid, &rem_dest->gid); | wire_gid_to_gid(gid, &rem_dest->gid); | ||||
if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest, sgid_idx)) { | if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest, | ||||
sgid_idx)) { | |||||
fprintf(stderr, "Couldn't connect to remote QP\n"); | fprintf(stderr, "Couldn't connect to remote QP\n"); | ||||
free(rem_dest); | free(rem_dest); | ||||
rem_dest = NULL; | rem_dest = NULL; | ||||
goto out; | goto out; | ||||
} | } | ||||
gid_to_wire_gid(&my_dest->gid, gid); | gid_to_wire_gid(&my_dest->gid, gid); | ||||
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid); | sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, | ||||
my_dest->psn, gid); | |||||
if (write(connfd, msg, sizeof msg) != sizeof msg) { | if (write(connfd, msg, sizeof msg) != sizeof msg) { | ||||
fprintf(stderr, "Couldn't send local address\n"); | fprintf(stderr, "Couldn't send local address\n"); | ||||
free(rem_dest); | free(rem_dest); | ||||
rem_dest = NULL; | rem_dest = NULL; | ||||
goto out; | goto out; | ||||
} | } | ||||
read(connfd, msg, sizeof msg); | /* expecting msg "done" */ | ||||
if (read(connfd, msg, sizeof(msg)) <= 0) { | |||||
fprintf(stderr, "Couldn't read \"done\" msg\n"); | |||||
free(rem_dest); | |||||
rem_dest = NULL; | |||||
goto out; | |||||
} | |||||
out: | out: | ||||
close(connfd); | close(connfd); | ||||
return rem_dest; | return rem_dest; | ||||
} | } | ||||
static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, | static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, | ||||
int rx_depth, int port, | int rx_depth, int port, | ||||
int use_event) | int use_event) | ||||
{ | { | ||||
struct pingpong_context *ctx; | struct pingpong_context *ctx; | ||||
ctx = malloc(sizeof *ctx); | ctx = malloc(sizeof *ctx); | ||||
if (!ctx) | if (!ctx) | ||||
return NULL; | return NULL; | ||||
ctx->size = size; | ctx->size = size; | ||||
ctx->rx_depth = rx_depth; | ctx->rx_depth = rx_depth; | ||||
ctx->buf = malloc(roundup(size + 40, page_size)); | ctx->buf = memalign(page_size, size + 40); | ||||
if (!ctx->buf) { | if (!ctx->buf) { | ||||
fprintf(stderr, "Couldn't allocate work buf.\n"); | fprintf(stderr, "Couldn't allocate work buf.\n"); | ||||
return NULL; | goto clean_ctx; | ||||
} | } | ||||
memset(ctx->buf, 0, size + 40); | /* FIXME memset(ctx->buf, 0, size + 40); */ | ||||
memset(ctx->buf, 0x7b, size + 40); | |||||
ctx->context = ibv_open_device(ib_dev); | ctx->context = ibv_open_device(ib_dev); | ||||
if (!ctx->context) { | if (!ctx->context) { | ||||
fprintf(stderr, "Couldn't get context for %s\n", | fprintf(stderr, "Couldn't get context for %s\n", | ||||
ibv_get_device_name(ib_dev)); | ibv_get_device_name(ib_dev)); | ||||
return NULL; | goto clean_buffer; | ||||
} | } | ||||
if (use_event) { | if (use_event) { | ||||
ctx->channel = ibv_create_comp_channel(ctx->context); | ctx->channel = ibv_create_comp_channel(ctx->context); | ||||
if (!ctx->channel) { | if (!ctx->channel) { | ||||
fprintf(stderr, "Couldn't create completion channel\n"); | fprintf(stderr, "Couldn't create completion channel\n"); | ||||
return NULL; | goto clean_device; | ||||
} | } | ||||
} else | } else | ||||
ctx->channel = NULL; | ctx->channel = NULL; | ||||
ctx->pd = ibv_alloc_pd(ctx->context); | ctx->pd = ibv_alloc_pd(ctx->context); | ||||
if (!ctx->pd) { | if (!ctx->pd) { | ||||
fprintf(stderr, "Couldn't allocate PD\n"); | fprintf(stderr, "Couldn't allocate PD\n"); | ||||
return NULL; | goto clean_comp_channel; | ||||
} | } | ||||
ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size + 40, IBV_ACCESS_LOCAL_WRITE); | ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size + 40, IBV_ACCESS_LOCAL_WRITE); | ||||
if (!ctx->mr) { | if (!ctx->mr) { | ||||
fprintf(stderr, "Couldn't register MR\n"); | fprintf(stderr, "Couldn't register MR\n"); | ||||
return NULL; | goto clean_pd; | ||||
} | } | ||||
ctx->cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL, | ctx->cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL, | ||||
ctx->channel, 0); | ctx->channel, 0); | ||||
if (!ctx->cq) { | if (!ctx->cq) { | ||||
fprintf(stderr, "Couldn't create CQ\n"); | fprintf(stderr, "Couldn't create CQ\n"); | ||||
return NULL; | goto clean_mr; | ||||
} | } | ||||
{ | { | ||||
struct ibv_qp_init_attr attr = { | struct ibv_qp_init_attr attr = { | ||||
.send_cq = ctx->cq, | .send_cq = ctx->cq, | ||||
.recv_cq = ctx->cq, | .recv_cq = ctx->cq, | ||||
.cap = { | .cap = { | ||||
.max_send_wr = 1, | .max_send_wr = 1, | ||||
.max_recv_wr = rx_depth, | .max_recv_wr = rx_depth, | ||||
.max_send_sge = 1, | .max_send_sge = 1, | ||||
.max_recv_sge = 1 | .max_recv_sge = 1 | ||||
}, | }, | ||||
.qp_type = IBV_QPT_UD, | .qp_type = IBV_QPT_UD, | ||||
}; | }; | ||||
ctx->qp = ibv_create_qp(ctx->pd, &attr); | ctx->qp = ibv_create_qp(ctx->pd, &attr); | ||||
if (!ctx->qp) { | if (!ctx->qp) { | ||||
fprintf(stderr, "Couldn't create QP\n"); | fprintf(stderr, "Couldn't create QP\n"); | ||||
return NULL; | goto clean_cq; | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
struct ibv_qp_attr attr = { | struct ibv_qp_attr attr = { | ||||
.qp_state = IBV_QPS_INIT, | .qp_state = IBV_QPS_INIT, | ||||
.pkey_index = 0, | .pkey_index = 0, | ||||
.port_num = port, | .port_num = port, | ||||
.qkey = 0x11111111 | .qkey = 0x11111111 | ||||
}; | }; | ||||
if (ibv_modify_qp(ctx->qp, &attr, | if (ibv_modify_qp(ctx->qp, &attr, | ||||
IBV_QP_STATE | | IBV_QP_STATE | | ||||
IBV_QP_PKEY_INDEX | | IBV_QP_PKEY_INDEX | | ||||
IBV_QP_PORT | | IBV_QP_PORT | | ||||
IBV_QP_QKEY)) { | IBV_QP_QKEY)) { | ||||
fprintf(stderr, "Failed to modify QP to INIT\n"); | fprintf(stderr, "Failed to modify QP to INIT\n"); | ||||
return NULL; | goto clean_qp; | ||||
} | } | ||||
} | } | ||||
return ctx; | return ctx; | ||||
clean_qp: | |||||
ibv_destroy_qp(ctx->qp); | |||||
clean_cq: | |||||
ibv_destroy_cq(ctx->cq); | |||||
clean_mr: | |||||
ibv_dereg_mr(ctx->mr); | |||||
clean_pd: | |||||
ibv_dealloc_pd(ctx->pd); | |||||
clean_comp_channel: | |||||
if (ctx->channel) | |||||
ibv_destroy_comp_channel(ctx->channel); | |||||
clean_device: | |||||
ibv_close_device(ctx->context); | |||||
clean_buffer: | |||||
free(ctx->buf); | |||||
clean_ctx: | |||||
free(ctx); | |||||
return NULL; | |||||
} | } | ||||
int pp_close_ctx(struct pingpong_context *ctx) | int pp_close_ctx(struct pingpong_context *ctx) | ||||
{ | { | ||||
if (ibv_destroy_qp(ctx->qp)) { | if (ibv_destroy_qp(ctx->qp)) { | ||||
fprintf(stderr, "Couldn't destroy QP\n"); | fprintf(stderr, "Couldn't destroy QP\n"); | ||||
return 1; | return 1; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | static void usage(const char *argv0) | ||||
printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n"); | printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n"); | ||||
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n"); | printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n"); | ||||
printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n"); | printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n"); | ||||
printf(" -s, --size=<size> size of message to exchange (default 1024)\n"); | printf(" -s, --size=<size> size of message to exchange (default 1024)\n"); | ||||
printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n"); | printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n"); | ||||
printf(" -n, --iters=<iters> number of exchanges (default 1000)\n"); | printf(" -n, --iters=<iters> number of exchanges (default 1000)\n"); | ||||
printf(" -e, --events sleep on CQ events (default poll)\n"); | printf(" -e, --events sleep on CQ events (default poll)\n"); | ||||
printf(" -g, --gid-idx=<gid index> local port gid index\n"); | printf(" -g, --gid-idx=<gid index> local port gid index\n"); | ||||
printf(" -6, --ipv6 use IPv6\n"); | |||||
} | } | ||||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||||
{ | { | ||||
struct ibv_device **dev_list; | struct ibv_device **dev_list; | ||||
struct ibv_device *ib_dev; | struct ibv_device *ib_dev; | ||||
struct pingpong_context *ctx; | struct pingpong_context *ctx; | ||||
struct pingpong_dest my_dest; | struct pingpong_dest my_dest; | ||||
struct pingpong_dest *rem_dest; | struct pingpong_dest *rem_dest; | ||||
struct timeval start, end; | struct timeval start, end; | ||||
char *ib_devname = NULL; | char *ib_devname = NULL; | ||||
char *servername = NULL; | char *servername = NULL; | ||||
int port = 18515; | int port = 18515; | ||||
int ib_port = 1; | int ib_port = 1; | ||||
int size = 1024; | int size = 1024; | ||||
int rx_depth = 500; | int rx_depth = 500; | ||||
int iters = 1000; | int iters = 1000; | ||||
int use_event = 0; | int use_event = 0; | ||||
int routs; | int routs; | ||||
int rcnt, scnt; | int rcnt, scnt; | ||||
int num_cq_events = 0; | int num_cq_events = 0; | ||||
int sl = 0; | int sl = 0; | ||||
int gidx = -1; | int gidx = -1; | ||||
char gid[33]; | char gid[INET6_ADDRSTRLEN]; | ||||
srand48(getpid() * time(NULL)); | srand48(getpid() * time(NULL)); | ||||
while (1) { | while (1) { | ||||
int c; | int c; | ||||
static struct option long_options[] = { | static struct option long_options[] = { | ||||
{ .name = "port", .has_arg = 1, .val = 'p' }, | { .name = "port", .has_arg = 1, .val = 'p' }, | ||||
{ .name = "ib-dev", .has_arg = 1, .val = 'd' }, | { .name = "ib-dev", .has_arg = 1, .val = 'd' }, | ||||
{ .name = "ib-port", .has_arg = 1, .val = 'i' }, | { .name = "ib-port", .has_arg = 1, .val = 'i' }, | ||||
{ .name = "size", .has_arg = 1, .val = 's' }, | { .name = "size", .has_arg = 1, .val = 's' }, | ||||
{ .name = "rx-depth", .has_arg = 1, .val = 'r' }, | { .name = "rx-depth", .has_arg = 1, .val = 'r' }, | ||||
{ .name = "iters", .has_arg = 1, .val = 'n' }, | { .name = "iters", .has_arg = 1, .val = 'n' }, | ||||
{ .name = "sl", .has_arg = 1, .val = 'l' }, | { .name = "sl", .has_arg = 1, .val = 'l' }, | ||||
{ .name = "events", .has_arg = 0, .val = 'e' }, | { .name = "events", .has_arg = 0, .val = 'e' }, | ||||
{ .name = "gid-idx", .has_arg = 1, .val = 'g' }, | { .name = "gid-idx", .has_arg = 1, .val = 'g' }, | ||||
{ .name = "ipv6", .has_arg = 0, .val = '6' }, | |||||
{ 0 } | { 0 } | ||||
}; | }; | ||||
c = getopt_long(argc, argv, "p:d:i:s:r:n:l:eg:", long_options, NULL); | c = getopt_long(argc, argv, "p:d:i:s:r:n:l:eg:6", | ||||
long_options, NULL); | |||||
if (c == -1) | if (c == -1) | ||||
break; | break; | ||||
switch (c) { | switch (c) { | ||||
case 'p': | case 'p': | ||||
port = strtol(optarg, NULL, 0); | port = strtol(optarg, NULL, 0); | ||||
if (port < 0 || port > 65535) { | if (port < 0 || port > 65535) { | ||||
usage(argv[0]); | usage(argv[0]); | ||||
return 1; | return 1; | ||||
} | } | ||||
break; | break; | ||||
case 'd': | case 'd': | ||||
ib_devname = strdup(optarg); | ib_devname = strdupa(optarg); | ||||
break; | break; | ||||
case 'i': | case 'i': | ||||
ib_port = strtol(optarg, NULL, 0); | ib_port = strtol(optarg, NULL, 0); | ||||
if (ib_port < 0) { | if (ib_port < 0) { | ||||
usage(argv[0]); | usage(argv[0]); | ||||
return 1; | return 1; | ||||
} | } | ||||
Show All 18 Lines | while (1) { | ||||
case 'e': | case 'e': | ||||
++use_event; | ++use_event; | ||||
break; | break; | ||||
case 'g': | case 'g': | ||||
gidx = strtol(optarg, NULL, 0); | gidx = strtol(optarg, NULL, 0); | ||||
break; | break; | ||||
case '6': | |||||
family = AF_INET6; | |||||
break; | |||||
default: | default: | ||||
usage(argv[0]); | usage(argv[0]); | ||||
return 1; | return 1; | ||||
} | } | ||||
} | } | ||||
if (optind == argc - 1) | if (optind == argc - 1) | ||||
servername = strdup(argv[optind]); | servername = strdupa(argv[optind]); | ||||
else if (optind < argc) { | else if (optind < argc) { | ||||
usage(argv[0]); | usage(argv[0]); | ||||
return 1; | return 1; | ||||
} | } | ||||
page_size = sysconf(_SC_PAGESIZE); | page_size = sysconf(_SC_PAGESIZE); | ||||
dev_list = ibv_get_device_list(NULL); | dev_list = ibv_get_device_list(NULL); | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | int main(int argc, char *argv[]) | ||||
} | } | ||||
my_dest.lid = ctx->portinfo.lid; | my_dest.lid = ctx->portinfo.lid; | ||||
my_dest.qpn = ctx->qp->qp_num; | my_dest.qpn = ctx->qp->qp_num; | ||||
my_dest.psn = lrand48() & 0xffffff; | my_dest.psn = lrand48() & 0xffffff; | ||||
if (gidx >= 0) { | if (gidx >= 0) { | ||||
if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) { | if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) { | ||||
fprintf(stderr, "Could not get local gid for gid index %d\n", gidx); | fprintf(stderr, "Could not get local gid for gid index " | ||||
"%d\n", gidx); | |||||
return 1; | return 1; | ||||
} | } | ||||
} else | } else | ||||
memset(&my_dest.gid, 0, sizeof my_dest.gid); | memset(&my_dest.gid, 0, sizeof my_dest.gid); | ||||
inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid); | inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid); | ||||
printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x: GID %s\n", | printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x: GID %s\n", | ||||
my_dest.lid, my_dest.qpn, my_dest.psn, gid); | my_dest.lid, my_dest.qpn, my_dest.psn, gid); | ||||
if (servername) | if (servername) | ||||
rem_dest = pp_client_exch_dest(servername, port, &my_dest); | rem_dest = pp_client_exch_dest(servername, port, &my_dest); | ||||
else | else | ||||
rem_dest = pp_server_exch_dest(ctx, ib_port, port, sl, &my_dest, gidx); | rem_dest = pp_server_exch_dest(ctx, ib_port, port, sl, | ||||
&my_dest, gidx); | |||||
if (!rem_dest) | if (!rem_dest) | ||||
return 1; | return 1; | ||||
inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid); | inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid); | ||||
printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", | printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", | ||||
rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); | rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); | ||||
if (servername) | if (servername) | ||||
if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest, gidx)) | if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest, | ||||
gidx)) | |||||
return 1; | return 1; | ||||
ctx->pending = PINGPONG_RECV_WRID; | ctx->pending = PINGPONG_RECV_WRID; | ||||
if (servername) { | if (servername) { | ||||
if (pp_post_send(ctx, rem_dest->qpn)) { | if (pp_post_send(ctx, rem_dest->qpn)) { | ||||
fprintf(stderr, "Couldn't post send\n"); | fprintf(stderr, "Couldn't post send\n"); | ||||
return 1; | return 1; | ||||
▲ Show 20 Lines • Show All 117 Lines • Show Last 20 Lines |