From patchwork Tue Jan 5 10:34:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Cohen X-Patchwork-Id: 70974 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o05AWnXH031852 for ; Tue, 5 Jan 2010 10:32:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754237Ab0AEKc2 (ORCPT ); Tue, 5 Jan 2010 05:32:28 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754272Ab0AEKc1 (ORCPT ); Tue, 5 Jan 2010 05:32:27 -0500 Received: from mail.mellanox.co.il ([194.90.237.43]:36987 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754237Ab0AEKcY (ORCPT ); Tue, 5 Jan 2010 05:32:24 -0500 Received: from Internal Mail-Server by MTLPINE1 (envelope-from eli@mellanox.co.il) with SMTP; 5 Jan 2010 12:32:22 +0200 Received: from localhost ([10.4.1.30]) by mtlexch01.mtl.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 5 Jan 2010 12:32:21 +0200 Date: Tue, 5 Jan 2010 12:34:15 +0200 From: Eli Cohen To: Roland Dreier Cc: Linux RDMA list Subject: [PATCH 4/4] libibverbs: Update examples Message-ID: <20100105103415.GO31480@mtls03> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-OriginalArrivalTime: 05 Jan 2010 10:32:22.0019 (UTC) FILETIME=[5D49A530:01CA8DF2] X-TM-AS-Product-Ver: SMEX-8.0.0.1181-6.000.1038-17112.006 X-TM-AS-Result: No--8.179600-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org diff --git a/examples/devinfo.c b/examples/devinfo.c index 84f95c7..393ec04 100644 --- a/examples/devinfo.c +++ b/examples/devinfo.c @@ -184,6 +184,19 @@ static int print_all_port_gids(struct ibv_context *ctx, uint8_t port_num, int tb return rc; } +static const char *link_layer_str(uint8_t link_layer) +{ + switch (link_layer) { + case IBV_LINK_LAYER_UNSPECIFIED: + case IBV_LINK_LAYER_INFINIBAND: + return "IB"; + case IBV_LINK_LAYER_ETHERNET: + return "Ethernet"; + default: + return "Unknown"; + } +} + static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port) { struct ibv_context *ctx; @@ -284,6 +297,7 @@ static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port) printf("\t\t\tsm_lid:\t\t\t%d\n", port_attr.sm_lid); printf("\t\t\tport_lid:\t\t%d\n", port_attr.lid); printf("\t\t\tport_lmc:\t\t0x%02x\n", port_attr.lmc); + printf("\t\t\tlink_layer:\t\t%s\n", link_layer_str(port_attr.link_layer)); if (verbose) { printf("\t\t\tmax_msg_sz:\t\t0x%x\n", port_attr.max_msg_sz); diff --git a/examples/pingpong.c b/examples/pingpong.c index b916f59..806f446 100644 --- a/examples/pingpong.c +++ b/examples/pingpong.c @@ -31,6 +31,10 @@ */ #include "pingpong.h" +#include +#include +#include +#include enum ibv_mtu pp_mtu_to_enum(int mtu) { @@ -53,3 +57,30 @@ uint16_t pp_get_local_lid(struct ibv_context *context, int port) return attr.lid; } + +int pp_get_port_info(struct ibv_context *context, int port, + struct ibv_port_attr *attr) +{ + return ibv_query_port(context, port, attr); +} + +void wire_gid_to_gid(const char *wgid, union ibv_gid *gid) +{ + char tmp[9]; + uint32_t v32; + int i; + + for (tmp[8] = 0, i = 0; i < 4; ++i) { + memcpy(tmp, wgid + i * 8, 8); + sscanf(tmp, "%x", &v32); + *(uint32_t *)(&gid->raw[i * 4]) = ntohl(v32); + } +} + +void gid_to_wire_gid(const union ibv_gid *gid, char wgid[]) +{ + int i; + + for (i = 0; i < 4; ++i) + sprintf(&wgid[i * 8], "%08x", htonl(*(uint32_t *)(gid->raw + i * 4))); +} diff --git a/examples/pingpong.h b/examples/pingpong.h index 71d7c3f..9cdc03e 100644 --- a/examples/pingpong.h +++ b/examples/pingpong.h @@ -37,5 +37,9 @@ enum ibv_mtu pp_mtu_to_enum(int mtu); uint16_t pp_get_local_lid(struct ibv_context *context, int port); +int pp_get_port_info(struct ibv_context *context, int port, + struct ibv_port_attr *attr); +void wire_gid_to_gid(const char *wgid, union ibv_gid *gid); +void gid_to_wire_gid(const union ibv_gid *gid, char wgid[]); #endif /* IBV_PINGPONG_H */ diff --git a/examples/rc_pingpong.c b/examples/rc_pingpong.c index fa969e0..7e35a20 100644 --- a/examples/rc_pingpong.c +++ b/examples/rc_pingpong.c @@ -67,12 +67,14 @@ struct pingpong_context { int size; int rx_depth; int pending; + struct ibv_port_attr portinfo; }; struct pingpong_dest { int lid; int qpn; int psn; + union ibv_gid gid; }; static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, @@ -94,6 +96,12 @@ static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, .port_num = port } }; + + if (dest->gid.global.interface_id) { + attr.ah_attr.is_global = 1; + attr.ah_attr.grh.hop_limit = 1; + attr.ah_attr.grh.dgid = dest->gid; + } if (ibv_modify_qp(ctx->qp, &attr, IBV_QP_STATE | IBV_QP_AV | @@ -135,10 +143,11 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -169,7 +178,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por return NULL; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); goto out; @@ -187,7 +197,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); out: close(sockfd); @@ -206,10 +217,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1, connfd; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -263,7 +275,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest)) { fprintf(stderr, "Couldn't connect to remote QP\n"); @@ -272,7 +285,9 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, goto out; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); free(rem_dest); @@ -289,11 +304,11 @@ out: static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, int rx_depth, int port, - int use_event) + int use_event, int is_server) { struct pingpong_context *ctx; - ctx = malloc(sizeof *ctx); + ctx = calloc(1, sizeof *ctx); if (!ctx) return NULL; @@ -306,7 +321,7 @@ static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, return NULL; } - memset(ctx->buf, 0, size); + memset(ctx->buf, 0x7b + is_server, size); ctx->context = ibv_open_device(ib_dev); if (!ctx->context) { @@ -481,6 +496,7 @@ static void usage(const char *argv0) printf(" -n, --iters= number of exchanges (default 1000)\n"); printf(" -l, --sl= service level value\n"); printf(" -e, --events sleep on CQ events (default poll)\n"); + printf(" -g, --gid-idx= local port gid index\n"); } int main(int argc, char *argv[]) @@ -504,6 +520,8 @@ int main(int argc, char *argv[]) int rcnt, scnt; int num_cq_events = 0; int sl = 0; + int gidx = -1; + char gid[33]; srand48(getpid() * time(NULL)); @@ -520,10 +538,11 @@ int main(int argc, char *argv[]) { .name = "iters", .has_arg = 1, .val = 'n' }, { .name = "sl", .has_arg = 1, .val = 'l' }, { .name = "events", .has_arg = 0, .val = 'e' }, + { .name = "gid-idx", .has_arg = 1, .val = 'g' }, { 0 } }; - c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:e", long_options, NULL); + c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL); if (c == -1) break; @@ -576,6 +595,10 @@ int main(int argc, char *argv[]) ++use_event; break; + case 'g': + gidx = strtol(optarg, NULL, 0); + break; + default: usage(argv[0]); return 1; @@ -615,7 +638,7 @@ int main(int argc, char *argv[]) } } - ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event); + ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event, !servername); if (!ctx) return 1; @@ -631,16 +654,32 @@ int main(int argc, char *argv[]) return 1; } - my_dest.lid = pp_get_local_lid(ctx->context, ib_port); - my_dest.qpn = ctx->qp->qp_num; - my_dest.psn = lrand48() & 0xffffff; - if (!my_dest.lid) { + + if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) { + fprintf(stderr, "Couldn't get port info\n"); + return 1; + } + + my_dest.lid = ctx->portinfo.lid; + if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) { fprintf(stderr, "Couldn't get local LID\n"); return 1; } - printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - my_dest.lid, my_dest.qpn, my_dest.psn); + if (gidx >= 0) { + 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); + return 1; + } + } else + memset(&my_dest.gid, 0, sizeof my_dest.gid); + + my_dest.qpn = ctx->qp->qp_num; + my_dest.psn = lrand48() & 0xffffff; + 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", + my_dest.lid, my_dest.qpn, my_dest.psn, gid); + if (servername) rem_dest = pp_client_exch_dest(servername, port, &my_dest); @@ -650,8 +689,9 @@ int main(int argc, char *argv[]) if (!rem_dest) return 1; - printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - rem_dest->lid, rem_dest->qpn, rem_dest->psn); + 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", + rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); if (servername) if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest)) @@ -706,6 +746,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "poll CQ failed %d\n", ne); return 1; } + } while (!use_event && ne < 1); for (i = 0; i < ne; ++i) { diff --git a/examples/srq_pingpong.c b/examples/srq_pingpong.c index 1e36c57..25ddfbc 100644 --- a/examples/srq_pingpong.c +++ b/examples/srq_pingpong.c @@ -71,12 +71,14 @@ struct pingpong_context { int num_qp; int rx_depth; int pending[MAX_QP]; + struct ibv_port_attr portinfo; }; struct pingpong_dest { int lid; int qpn; int psn; + union ibv_gid gid; }; static int pp_connect_ctx(struct pingpong_context *ctx, int port, enum ibv_mtu mtu, @@ -101,6 +103,12 @@ static int pp_connect_ctx(struct pingpong_context *ctx, int port, enum ibv_mtu m .port_num = port } }; + + if (dest->gid.global.interface_id) { + attr.ah_attr.is_global = 1; + attr.ah_attr.grh.hop_limit = 1; + attr.ah_attr.grh.dgid = dest->gid; + } if (ibv_modify_qp(ctx->qp[i], &attr, IBV_QP_STATE | IBV_QP_AV | @@ -143,12 +151,13 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int r; int i; int sockfd = -1; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -180,7 +189,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por } for (i = 0; i < MAX_QP; ++i) { - sprintf(msg, "%04x:%06x:%06x", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn); + gid_to_wire_gid(&my_dest[i].gid, gid); + sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid); if (write(sockfd, msg, sizeof msg) != sizeof msg) { fprintf(stderr, "Couldn't send local address\n"); goto out; @@ -204,8 +214,9 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por n += r; } - sscanf(msg, "%x:%x:%x", - &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn); + sscanf(msg, "%x:%x:%x:%s", + &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid); + wire_gid_to_gid(gid, &rem_dest[i].gid); } write(sockfd, "done", sizeof "done"); @@ -227,12 +238,13 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int r; int i; int sockfd = -1, connfd; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -292,8 +304,9 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, n += r; } - sscanf(msg, "%x:%x:%x", - &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn); + sscanf(msg, "%x:%x:%x:%s", + &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid); + wire_gid_to_gid(gid, &rem_dest[i].gid); } if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest)) { @@ -304,7 +317,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, } for (i = 0; i < MAX_QP; ++i) { - sprintf(msg, "%04x:%06x:%06x", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn); + gid_to_wire_gid(&my_dest[i].gid, gid); + sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid); if (write(connfd, msg, sizeof msg) != sizeof msg) { fprintf(stderr, "Couldn't send local address\n"); free(rem_dest); @@ -327,7 +341,7 @@ static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, struct pingpong_context *ctx; int i; - ctx = malloc(sizeof *ctx); + ctx = calloc(1, sizeof *ctx); if (!ctx) return NULL; @@ -551,6 +565,7 @@ static void usage(const char *argv0) printf(" -n, --iters= number of exchanges per QP(default 1000)\n"); printf(" -l, --sl= service level value\n"); printf(" -e, --events sleep on CQ events (default poll)\n"); + printf(" -g, --gid-idx= local port gid index\n"); } int main(int argc, char *argv[]) @@ -578,6 +593,8 @@ int main(int argc, char *argv[]) int i; int num_cq_events = 0; int sl = 0; + int gidx = -1; + char gid[33]; srand48(getpid() * time(NULL)); @@ -595,10 +612,11 @@ int main(int argc, char *argv[]) { .name = "iters", .has_arg = 1, .val = 'n' }, { .name = "sl", .has_arg = 1, .val = 'l' }, { .name = "events", .has_arg = 0, .val = 'e' }, + { .name = "gid-idx", .has_arg = 1, .val = 'g' }, { 0 } }; - c = getopt_long(argc, argv, "p:d:i:s:m:q:r:n:l:e", long_options, NULL); + c = getopt_long(argc, argv, "p:d:i:s:m:q:r:n:l:eg:", long_options, NULL); if (c == -1) break; @@ -655,6 +673,10 @@ int main(int argc, char *argv[]) ++use_event; break; + case 'g': + gidx = strtol(optarg, NULL, 0); + break; + default: usage(argv[0]); return 1; @@ -722,17 +744,29 @@ int main(int argc, char *argv[]) memset(my_dest, 0, sizeof my_dest); + if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) { + fprintf(stderr, "Couldn't get port info\n"); + return 1; + } for (i = 0; i < num_qp; ++i) { my_dest[i].qpn = ctx->qp[i]->qp_num; my_dest[i].psn = lrand48() & 0xffffff; - my_dest[i].lid = pp_get_local_lid(ctx->context, ib_port); - if (!my_dest[i].lid) { + if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest[i].lid) { fprintf(stderr, "Couldn't get local LID\n"); return 1; } - printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn); + if (gidx >= 0) { + if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest[i].gid)) { + fprintf(stderr, "Could not get local gid for gid index %d\n", gidx); + return 1; + } + } else + memset(&my_dest[i].gid, 0, sizeof my_dest[i].gid); + + inet_ntop(AF_INET6, &my_dest[i].gid, gid, sizeof gid); + printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", + my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid); } if (servername) @@ -743,9 +777,13 @@ int main(int argc, char *argv[]) if (!rem_dest) return 1; - for (i = 0; i < num_qp; ++i) - printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - rem_dest[i].lid, rem_dest[i].qpn, rem_dest[i].psn); + inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid); + + for (i = 0; i < num_qp; ++i) { + inet_ntop(AF_INET6, &rem_dest[i].gid, gid, sizeof gid); + printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", + rem_dest[i].lid, rem_dest[i].qpn, rem_dest[i].psn, gid); + } if (servername) if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest)) diff --git a/examples/uc_pingpong.c b/examples/uc_pingpong.c index 6f31247..eefc320 100644 --- a/examples/uc_pingpong.c +++ b/examples/uc_pingpong.c @@ -67,12 +67,14 @@ struct pingpong_context { int size; int rx_depth; int pending; + struct ibv_port_attr portinfo; }; struct pingpong_dest { int lid; int qpn; int psn; + union ibv_gid gid; }; static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, @@ -92,6 +94,13 @@ static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, .port_num = port } }; + + if (dest->gid.global.interface_id) { + attr.ah_attr.is_global = 1; + attr.ah_attr.grh.hop_limit = 1; + attr.ah_attr.grh.dgid = dest->gid; + } + if (ibv_modify_qp(ctx->qp, &attr, IBV_QP_STATE | IBV_QP_AV | @@ -123,10 +132,11 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -157,7 +167,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por return NULL; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); goto out; @@ -175,7 +186,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); out: close(sockfd); @@ -194,10 +206,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1, connfd; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -251,7 +264,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest)) { fprintf(stderr, "Couldn't connect to remote QP\n"); @@ -260,7 +274,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, goto out; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); free(rem_dest); @@ -281,7 +296,7 @@ static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, { struct pingpong_context *ctx; - ctx = malloc(sizeof *ctx); + ctx = calloc(1, sizeof *ctx); if (!ctx) return NULL; @@ -469,6 +484,7 @@ static void usage(const char *argv0) printf(" -n, --iters= number of exchanges (default 1000)\n"); printf(" -l, --sl= service level value\n"); printf(" -e, --events sleep on CQ events (default poll)\n"); + printf(" -g, --gid-idx= local port gid index\n"); } int main(int argc, char *argv[]) @@ -492,6 +508,8 @@ int main(int argc, char *argv[]) int rcnt, scnt; int num_cq_events = 0; int sl = 0; + int gidx = -1; + char gid[33]; srand48(getpid() * time(NULL)); @@ -508,10 +526,11 @@ int main(int argc, char *argv[]) { .name = "iters", .has_arg = 1, .val = 'n' }, { .name = "sl", .has_arg = 1, .val = 'l' }, { .name = "events", .has_arg = 0, .val = 'e' }, + { .name = "gid-idx", .has_arg = 1, .val = 'g' }, { 0 } }; - c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:e", long_options, NULL); + c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL); if (c == -1) break; @@ -564,6 +583,10 @@ int main(int argc, char *argv[]) ++use_event; break; + case 'g': + gidx = strtol(optarg, NULL, 0); + break; + default: usage(argv[0]); return 1; @@ -619,16 +642,30 @@ int main(int argc, char *argv[]) return 1; } - my_dest.lid = pp_get_local_lid(ctx->context, ib_port); - my_dest.qpn = ctx->qp->qp_num; - my_dest.psn = lrand48() & 0xffffff; - if (!my_dest.lid) { + if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) { + fprintf(stderr, "Couldn't get port info\n"); + return 1; + } + + my_dest.lid = ctx->portinfo.lid; + if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) { fprintf(stderr, "Couldn't get local LID\n"); return 1; } - printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - my_dest.lid, my_dest.qpn, my_dest.psn); + if (gidx >= 0) { + 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); + return 1; + } + } else + memset(&my_dest.gid, 0, sizeof my_dest.gid); + + my_dest.qpn = ctx->qp->qp_num; + my_dest.psn = lrand48() & 0xffffff; + 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", + my_dest.lid, my_dest.qpn, my_dest.psn, gid); if (servername) rem_dest = pp_client_exch_dest(servername, port, &my_dest); @@ -638,8 +675,9 @@ int main(int argc, char *argv[]) if (!rem_dest) return 1; - printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - rem_dest->lid, rem_dest->qpn, rem_dest->psn); + 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", + rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); if (servername) if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest)) diff --git a/examples/ud_pingpong.c b/examples/ud_pingpong.c index 6f10212..c752f84 100644 --- a/examples/ud_pingpong.c +++ b/examples/ud_pingpong.c @@ -68,12 +68,14 @@ struct pingpong_context { int size; int rx_depth; int pending; + struct ibv_port_attr portinfo; }; struct pingpong_dest { int lid; int qpn; int psn; + union ibv_gid gid; }; static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, @@ -105,6 +107,12 @@ static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, return 1; } + if (dest->gid.global.interface_id) { + ah_attr.is_global = 1; + ah_attr.grh.hop_limit = 1; + ah_attr.grh.dgid = dest->gid; + } + ctx->ah = ibv_create_ah(ctx->pd, &ah_attr); if (!ctx->ah) { fprintf(stderr, "Failed to create AH\n"); @@ -123,10 +131,11 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -157,7 +166,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por return NULL; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); goto out; @@ -175,7 +185,8 @@ static struct pingpong_dest *pp_client_exch_dest(const char *servername, int por if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); out: close(sockfd); @@ -193,10 +204,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, .ai_socktype = SOCK_STREAM }; char *service; - char msg[sizeof "0000:000000:000000"]; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; int n; int sockfd = -1, connfd; struct pingpong_dest *rem_dest = NULL; + char gid[33]; if (asprintf(&service, "%d", port) < 0) return NULL; @@ -250,7 +262,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, if (!rem_dest) goto out; - sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn); + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest)) { fprintf(stderr, "Couldn't connect to remote QP\n"); @@ -259,7 +272,8 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, goto out; } - sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn); + gid_to_wire_gid(&my_dest->gid, 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) { fprintf(stderr, "Couldn't send local address\n"); free(rem_dest); @@ -474,10 +488,11 @@ static void usage(const char *argv0) printf(" -p, --port= listen on/connect to port (default 18515)\n"); printf(" -d, --ib-dev= use IB device (default first device found)\n"); printf(" -i, --ib-port= use port of IB device (default 1)\n"); - printf(" -s, --size= size of message to exchange (default 2048)\n"); + printf(" -s, --size= size of message to exchange (default 1024)\n"); printf(" -r, --rx-depth= number of receives to post at a time (default 500)\n"); printf(" -n, --iters= number of exchanges (default 1000)\n"); printf(" -e, --events sleep on CQ events (default poll)\n"); + printf(" -g, --gid-idx= local port gid index\n"); } int main(int argc, char *argv[]) @@ -492,7 +507,7 @@ int main(int argc, char *argv[]) char *servername = NULL; int port = 18515; int ib_port = 1; - int size = 2048; + int size = 1024; int rx_depth = 500; int iters = 1000; int use_event = 0; @@ -500,6 +515,8 @@ int main(int argc, char *argv[]) int rcnt, scnt; int num_cq_events = 0; int sl = 0; + int gidx = -1; + char gid[33]; srand48(getpid() * time(NULL)); @@ -515,10 +532,11 @@ int main(int argc, char *argv[]) { .name = "iters", .has_arg = 1, .val = 'n' }, { .name = "sl", .has_arg = 1, .val = 'l' }, { .name = "events", .has_arg = 0, .val = 'e' }, + { .name = "gid-idx", .has_arg = 1, .val = 'g' }, { 0 } }; - c = getopt_long(argc, argv, "p:d:i:s:r:n:l:e", long_options, NULL); + c = getopt_long(argc, argv, "p:d:i:s:r:n:l:eg:", long_options, NULL); if (c == -1) break; @@ -563,6 +581,10 @@ int main(int argc, char *argv[]) ++use_event; break; + case 'g': + gidx = strtol(optarg, NULL, 0); + break; + default: usage(argv[0]); return 1; @@ -618,16 +640,26 @@ int main(int argc, char *argv[]) return 1; } - my_dest.lid = pp_get_local_lid(ctx->context, ib_port); - my_dest.qpn = ctx->qp->qp_num; - my_dest.psn = lrand48() & 0xffffff; - if (!my_dest.lid) { - fprintf(stderr, "Couldn't get local LID\n"); + if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) { + fprintf(stderr, "Couldn't get port info\n"); return 1; } + my_dest.lid = ctx->portinfo.lid; + + my_dest.qpn = ctx->qp->qp_num; + my_dest.psn = lrand48() & 0xffffff; + + if (gidx >= 0) { + 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); + return 1; + } + } else + memset(&my_dest.gid, 0, sizeof my_dest.gid); - printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - my_dest.lid, my_dest.qpn, my_dest.psn); + 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", + my_dest.lid, my_dest.qpn, my_dest.psn, gid); if (servername) rem_dest = pp_client_exch_dest(servername, port, &my_dest); @@ -637,8 +669,9 @@ int main(int argc, char *argv[]) if (!rem_dest) return 1; - printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n", - rem_dest->lid, rem_dest->qpn, rem_dest->psn); + 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", + rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); if (servername) if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest))