From aba9933e4f9a0a2e5806635f381536bcb6b2906a Mon Sep 17 00:00:00 2001 From: "Paul H. Hargrove" <PHHargrove@lbl.gov> Date: Mon, 10 Dec 2018 19:33:28 -0800 Subject: [PATCH] ibv: add support for non-default IB Partition Key This commit implements and documents environment variable "GASNET_IBV_PKEY" to allow selection of a non-default InfiniBand partition key. --- ibv-conduit/README | 6 +++++ ibv-conduit/gasnet_core.c | 39 ++++++++++++++++++++++++++++++ ibv-conduit/gasnet_core_connect.c | 4 +-- ibv-conduit/gasnet_core_internal.h | 1 + 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ibv-conduit/README b/ibv-conduit/README index 5c48b72b4..2d4f7be96 100644 --- a/ibv-conduit/README +++ b/ibv-conduit/README @@ -236,6 +236,12 @@ Paul H. Hargrove <PHHargrove@lbl.gov> the available HCAs and the status of their ports. The default is no filter. + + GASNET_IBV_PKEY + If set, this specifies the 15-bit InfiniBand Partition Key to use. + Valid values are in the range 2 to 0x7fff. + For compatibility, the membership bit (0x8000) is ignored. + The default is to use the Partition Key installed at table index 0. + + GASNET_QP_TIMEOUT This sets the timeout value used to configure InfiniBand QueuePairs. The IB specification uses (4.096us * 2^qp_timeout) as the length of diff --git a/ibv-conduit/gasnet_core.c b/ibv-conduit/gasnet_core.c index 750b1c94a..ad3541f3f 100644 --- a/ibv-conduit/gasnet_core.c +++ b/ibv-conduit/gasnet_core.c @@ -17,6 +17,10 @@ #include <sys/time.h> #include <sys/resource.h> +// ntohs() should be in one of these: +#include <netinet/in.h> +#include <arpa/inet.h> + GASNETI_IDENT(gasnetc_IdentString_Version, "$GASNetCoreLibraryVersion: " GASNET_CORE_VERSION_STR " $"); GASNETI_IDENT(gasnetc_IdentString_Name, "$GASNetCoreLibraryName: " GASNET_CORE_NAME_STR " $"); @@ -1470,6 +1474,17 @@ static void gasnetc_probe_ports(int max_ports) { "'gasnet/ibv-conduit/README'.\n", num_hcas, current, enable, num_hcas); } + int64_t pkey = gasnett_getenv_int_withdefault("GASNET_IBV_PKEY", -1, 0); + uint64_t pkey_mask = ~(uint64_t)0x8000; // to strip membership bit + if (pkey == -1) { + // Nothing to do + } else { + pkey &= pkey_mask; + if ((pkey > 0x7fff) || (pkey < 2)) { + gasneti_fatalerror("Invalid GASNET_IBV_PKEY '%s'", gasnett_getenv("GASNET_IBV_PKEY")); + } + } + /* Loop over list of HCAs */ for (curr_hca = 0; (hca_count < GASNETC_IB_MAX_HCAS) && (port_count < max_ports) && (curr_hca < num_hcas); @@ -1526,6 +1541,30 @@ static void gasnetc_probe_ports(int max_ports) { ++found; this_port->port_num = curr_port; this_port->hca_index = hca_count; + if (pkey < 0) { + GASNETI_TRACE_PRINTF(C,("Using default pkey_index=0 for HCA '%s', port %d", + hca_name, curr_port)); + this_port->pkey_index = 0; + } else { + int i; + for (i = 0; i < hca_cap.max_pkeys; ++i) { + uint16_t pkey_val; + if (ibv_query_pkey(hca_handle, curr_port, i, &pkey_val)) { + gasneti_fatalerror("Failed to query pkeys for HCA '%s', port %d", hca_name, curr_port); + } + pkey_val = ntohs(pkey_val) & pkey_mask; + if (pkey_val == pkey) { + GASNETI_TRACE_PRINTF(C,("Using pkey_index %d for HCA '%s', port %d", + i, hca_name, curr_port)); + this_port->pkey_index = i; + break; + } + } + if (i == hca_cap.max_pkeys) { + gasneti_fatalerror("Failed to locate index of requested pkey 0x%04x for HCA '%s', port %d", + (unsigned int)pkey, hca_name, curr_port); + } + } if (gasnetc_qp_rd_atom) { /* Zero means use HCA/port limit */ int limit = MIN(hca_cap.max_qp_init_rd_atom, hca_cap.max_qp_rd_atom); if (gasnetc_qp_rd_atom > limit) { diff --git a/ibv-conduit/gasnet_core_connect.c b/ibv-conduit/gasnet_core_connect.c index 65b4a4477..647f3806a 100644 --- a/ibv-conduit/gasnet_core_connect.c +++ b/ibv-conduit/gasnet_core_connect.c @@ -632,7 +632,6 @@ gasnetc_qp_reset2init(gasnetc_conn_info_t *conn_info) qp_mask = (enum ibv_qp_attr_mask)(IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS); qp_attr.qp_state = IBV_QPS_INIT; - qp_attr.pkey_index = 0; qp_attr.qp_access_flags = IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ; GASNETC_FOR_EACH_QPI(conn_info, qpi, cep) { @@ -644,6 +643,7 @@ gasnetc_qp_reset2init(gasnetc_conn_info_t *conn_info) : IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ; #endif qp_attr.port_num = port->port_num; + qp_attr.pkey_index = port->pkey_index; #if GASNETC_IBV_XRC if (gasnetc_use_xrc) { @@ -1308,7 +1308,7 @@ gasnetc_qp_setup_ud(gasnetc_port_info_t *port, int fully_connected) /* RESET -> INIT */ qp_mask = (enum ibv_qp_attr_mask)(IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_QKEY); qp_attr.qp_state = IBV_QPS_INIT; - qp_attr.pkey_index = 0; + qp_attr.pkey_index = port->pkey_index; qp_attr.qkey = my_qkey; qp_attr.port_num = port->port_num; rc = ibv_modify_qp(conn_ud_qp, &qp_attr, qp_mask); diff --git a/ibv-conduit/gasnet_core_internal.h b/ibv-conduit/gasnet_core_internal.h index d373ffd9a..eb9b8836f 100644 --- a/ibv-conduit/gasnet_core_internal.h +++ b/ibv-conduit/gasnet_core_internal.h @@ -599,6 +599,7 @@ struct gasnetc_cep_t_ { typedef struct { int hca_index; /* Slot in gasnetc_hca[] */ uint8_t port_num; /* Port number */ + uint16_t pkey_index; struct ibv_port_attr port; /* Port info */ int rd_atom; uint16_t *remote_lids; -- 2.48.1