Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMI/GSI pair suggestion #1529

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions debian/libibmad5.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,6 @@ libibmad.so.5 libibmad5 #MINVER#
smp_set_via@IBMAD_1.3 1.3.11
str2drpath@IBMAD_1.3 1.3.11
xdump@IBMAD_1.3 1.3.11
mad_rpc_open_port2@IBMAD_1.5 5.55.0
mad_rpc_close_port2@IBMAD_1.5 5.55.0

2 changes: 2 additions & 0 deletions debian/libibumad3.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ libibumad.so.3 libibumad3 #MINVER#
umad_sort_ca_device_list@IBUMAD_1.2 3.2.30
umad_status@IBUMAD_1.0 1.3.9
umad_unregister@IBUMAD_1.0 1.3.9
umad_get_smi_gsi_pairs@IBUMAD_1.4 3.4.55
umad_get_smi_gsi_pair_by_ca_name@IBUMAD_1.4 3.4.55
15 changes: 9 additions & 6 deletions infiniband-diags/smpquery.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "ibdiag_common.h"

static struct ibmad_port *srcport;
static struct ibmad_ports_pair *srcports;

static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table,
sl2vl_table, vlarb_table, guid_info, mlnx_ext_port_info, port_info_extended;
Expand Down Expand Up @@ -475,17 +476,19 @@ int main(int argc, char **argv)
if (!(fn = match_op(match_tbl, argv[0])))
IBEXIT("operation '%s' not supported", argv[0]);

srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
if (!srcport)
srcports = mad_rpc_open_port2(ibd_ca, ibd_ca_port, mgmt_classes, 3, 1);
if (!srcports)
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);

srcport = srcports->smi.port;

smp_mkey_set(srcport, ibd_mkey);

node_name_map = open_node_name_map(node_name_map_file);

if (ibd_dest_type != IB_DEST_DRSLID) {
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1],
ibd_dest_type, ibd_sm_id, srcport) < 0)
if (resolve_portid_str(srcports->gsi.ca_name, ibd_ca_port, &portid, argv[1],
ibd_dest_type, ibd_sm_id, srcports->gsi.port) < 0)
IBEXIT("can't resolve destination port %s", argv[1]);
if ((err = fn(&portid, argv + 2, argc - 2)))
IBEXIT("operation %s: %s", argv[0], err);
Expand All @@ -494,13 +497,13 @@ int main(int argc, char **argv)

memset(concat, 0, 64);
snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]);
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, concat,
if (resolve_portid_str(srcports->smi.ca_name, ibd_ca_port, &portid, concat,
ibd_dest_type, ibd_sm_id, srcport) < 0)
IBEXIT("can't resolve destination port %s", concat);
if ((err = fn(&portid, argv + 3, argc - 3)))
IBEXIT("operation %s: %s", argv[0], err);
}
close_node_name_map(node_name_map);
mad_rpc_close_port(srcport);
mad_rpc_close_port2(srcports);
exit(0);
}
2 changes: 1 addition & 1 deletion libibmad/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ publish_internal_headers(util

rdma_library(ibmad libibmad.map
# See Documentation/versioning.md
5 5.4.${PACKAGE_VERSION}
5 5.5.${PACKAGE_VERSION}
bm.c
cc.c
dump.c
Expand Down
7 changes: 7 additions & 0 deletions libibmad/libibmad.map
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,10 @@ IBMAD_1.4 {
mad_dump_linkspeedexten2;
mad_dump_linkspeedextsup2;
} IBMAD_1.3;

IBMAD_1.5 {
global:
mad_rpc_open_port2;
mad_rpc_close_port2;
} IBMAD_1.4;

13 changes: 13 additions & 0 deletions libibmad/mad.h
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,16 @@ typedef struct ib_bm_call {
uint64_t bkey;
} ib_bm_call_t;

typedef struct ibmad_ports_item {
struct ibmad_port *port;
char ca_name[20];
} ibmad_ports_item_t;

struct ibmad_ports_pair {
ibmad_ports_item_t smi;
ibmad_ports_item_t gsi;
};

#define IB_MIN_UCAST_LID 1
#define IB_MAX_UCAST_LID (0xc000-1)
#define IB_MIN_MCAST_LID 0xc000
Expand Down Expand Up @@ -1483,7 +1493,10 @@ int madrpc_set_retries(int retries);
int madrpc_set_timeout(int timeout);
struct ibmad_port *mad_rpc_open_port(char *dev_name, int dev_port,
int *mgmt_classes, int num_classes);
struct ibmad_ports_pair *mad_rpc_open_port2(char *dev_name, int dev_port,
int *mgmt_classes, int num_classes, unsigned enforce_smi);
void mad_rpc_close_port(struct ibmad_port *srcport);
void mad_rpc_close_port2(struct ibmad_ports_pair *srcport);

/*
* On redirection, the dport argument is updated with the redirection target,
Expand Down
130 changes: 130 additions & 0 deletions libibmad/rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,133 @@ void mad_rpc_close_port(struct ibmad_port *port)
umad_close_port(port->port_id);
free(port);
}

static int get_smi_gsi_pair(const char *ca_name, int portnum, struct ibmad_ports_pair *ports_pair,
unsigned enforce_smi)
{
struct umad_ca_pair ca_pair;
int smi_port_id = -1;
int gsi_port_id = -1;
int rc = -1;
rc = umad_get_smi_gsi_pair_by_ca_name(ca_name, portnum, &ca_pair, enforce_smi);

if (rc < 0) {
IBWARN("Can't open UMAD port (%s) (%s:%d)", strerror(-rc), ca_name, portnum);
return rc;
}

smi_port_id = umad_open_port(ca_pair.smi_name, ca_pair.smi_preferred_port);

if (smi_port_id < 0) {
IBWARN("Can't open SMI UMAD port (%s) (%s:%d)", strerror(-smi_port_id), ca_pair.smi_name, ca_pair.smi_preferred_port);
return smi_port_id;
}

gsi_port_id = umad_open_port(ca_pair.gsi_name, ca_pair.gsi_preferred_port);

if (gsi_port_id < 0) {
IBWARN("Can't open GSI UMAD port (%s) (%s:%d)", strerror(-gsi_port_id), ca_pair.gsi_name, ca_pair.gsi_preferred_port);
umad_close_port(smi_port_id);
return gsi_port_id;
}

ports_pair->smi.port->port_id = smi_port_id;
ports_pair->gsi.port->port_id = gsi_port_id;
strncpy(ports_pair->smi.ca_name, ca_pair.smi_name, UMAD_CA_NAME_LEN);
strncpy(ports_pair->gsi.ca_name, ca_pair.gsi_name, UMAD_CA_NAME_LEN);

return 0;
}

struct ibmad_ports_pair *mad_rpc_open_port2(char *dev_name, int dev_port,
int *mgmt_classes, int num_classes, unsigned enforce_smi)
{
struct ibmad_port *smi;
struct ibmad_port *gsi;
struct ibmad_ports_pair *ports_pair;
char *debug_level_env;

if (num_classes >= MAX_CLASS) {
IBWARN("too many classes %d requested", num_classes);
errno = EINVAL;
return NULL;
}

if (umad_init() < 0) {
IBWARN("can't init UMAD library");
errno = ENODEV;
return NULL;
}

debug_level_env = getenv("LIBIBMAD_DEBUG_LEVEL");
if (debug_level_env) {
ibdebug = atoi(debug_level_env);
}

smi = malloc(sizeof(*smi));
if (!smi) {
errno = ENOMEM;
return NULL;
}
memset(smi, 0, sizeof(*smi));

gsi = malloc(sizeof(*gsi));
if (!gsi) {
errno = ENOMEM;
return NULL;
}
memset(gsi, 0, sizeof(*gsi));

ports_pair = malloc(sizeof(*ports_pair));
if (!ports_pair) {
errno = ENOMEM;
return NULL;
}
memset(ports_pair, 0, sizeof(*ports_pair));
ports_pair->smi.port = smi;
ports_pair->gsi.port = gsi;

if ((get_smi_gsi_pair(dev_name, dev_port, ports_pair, enforce_smi)) < 0) {
IBWARN("can't open UMAD port (%s:%d)", dev_name, dev_port);
if (!errno)
errno = EIO;
free(smi);
free(gsi);
free(ports_pair);
return NULL;
}

memset(ports_pair->smi.port->class_agents, 0xff, sizeof ports_pair->smi.port->class_agents);
memset(ports_pair->gsi.port->class_agents, 0xff, sizeof ports_pair->gsi.port->class_agents);
while (num_classes--) {
uint8_t rmpp_version = 0;
int mgmt = *mgmt_classes++;
struct ibmad_port *p = (mgmt == IB_SMI_CLASS || mgmt == IB_SMI_DIRECT_CLASS) ?
ports_pair->smi.port : ports_pair->gsi.port;
if (mgmt == IB_SA_CLASS)
rmpp_version = 1;
if (mgmt < 0 || mgmt >= MAX_CLASS ||
mad_register_client_via(mgmt, rmpp_version, p) < 0) {
IBWARN("client_register for mgmt %d failed", mgmt);
if (!errno)
errno = EINVAL;
umad_close_port(ports_pair->smi.port->port_id);
umad_close_port(ports_pair->gsi.port->port_id);
free(ports_pair->smi.port);
free(ports_pair->gsi.port);
free(ports_pair);
return NULL;
}
}

return ports_pair;
}

void mad_rpc_close_port2(struct ibmad_ports_pair *srcport)
{
umad_close_port(srcport->smi.port->port_id);
umad_close_port(srcport->gsi.port->port_id);
free(srcport->smi.port);
free(srcport->gsi.port);
free(srcport);
}
2 changes: 1 addition & 1 deletion libibumad/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ publish_headers(infiniband

rdma_library(ibumad libibumad.map
# See Documentation/versioning.md
3 3.3.${PACKAGE_VERSION}
3 3.4.${PACKAGE_VERSION}
sysfs.c
umad.c
umad_str.c
Expand Down
7 changes: 7 additions & 0 deletions libibumad/libibumad.map
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,10 @@ IBUMAD_1.3 {
global:
umad_open_smi_port;
} IBUMAD_1.2;

IBUMAD_1.4 {
global:
umad_get_smi_gsi_pairs;
umad_get_smi_gsi_pair_by_ca_name;
} IBUMAD_1.3;

54 changes: 54 additions & 0 deletions libibumad/man/umad_get_smi_gsi_pair_by_ca_name.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.. -*- rst -*-
.. Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md

umad_get_smi_gsi_pair_by_ca_name(3)
===================================

Retrieve SMI/GSI pair information based on device name and port number.

Synopsis
--------

.. code-block:: c

#include <infiniband/umad.h>

int umad_get_smi_gsi_pair_by_ca_name(const char *devname, uint8_t portnum, struct umad_ca_pair *ca);

Description
-----------

``umad_get_smi_gsi_pair_by_ca_name()`` fills the provided ``ca`` structure with the SMI and GSI pair information
for the specified device name and port number.

The ``devname`` parameter specifies the name of the device, and ``portnum`` is the associated port number.

The ``struct umad_ca_pair`` is defined in ``<infiniband/umad.h>`` and includes the following members:

.. code-block:: c

struct umad_ca_pair {
char smi_name[UMAD_CA_NAME_LEN];
/* Name of the SMI */
uint32_t smi_preferred_port;
/* Preferred port for the SMI */
char gsi_name[UMAD_CA_NAME_LEN];
/* Name of the GSI */
uint32_t gsi_preferred_port;
/* Preferred port for the GSI */
};

The function populates this structure with the relevant data for the given ``devname`` and ``portnum``.

Return Value
------------

``umad_get_smi_gsi_pair_by_ca_name()`` returns:

- **0**: If the specified device and port are found and the structure is successfully populated.
- **1**: If no matching device or port is found.

Authors
-------

- Asaf Mazor <[email protected]>
50 changes: 50 additions & 0 deletions libibumad/man/umad_get_smi_gsi_pairs.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.. -*- rst -*-
.. Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md

umad_get_smi_gsi_pairs(3)
=========================

Get CAs as SMI/GSI pairs.

Synopsis
--------

.. code-block:: c

#include <infiniband/umad.h>

int umad_get_smi_gsi_pairs(struct umad_ca_pair cas[], size_t max);

Description
-----------

``umad_get_smi_gsi_pairs()`` fills a user-allocated array of ``struct umad_ca_pair``.
It fills up to ``max`` devices.

The argument ``cas`` is an array of ``struct umad_ca_pair`` as specified in ``<infiniband/umad.h>``:

.. code-block:: c

struct umad_ca_pair {
char smi_name[UMAD_CA_NAME_LEN];
/* Name of the SMI */
uint32_t smi_preferred_port;
/* Preferred port for the SMI */
char gsi_name[UMAD_CA_NAME_LEN];
/* Name of the GSI */
uint32_t gsi_preferred_port;
/* Preferred port for the GSI */
};

The ``smi_preferred_port`` and ``gsi_preferred_port`` fields represent the first ports found active
for the corresponding SMI/GSI device.

Return Value
------------

``umad_get_smi_gsi_pairs()`` returns the number of devices filled, or **-1** on error.

Authors
-------

- Asaf Mazor <[email protected]>
Loading