Fix ibv_port_query() usnic extension usage
* Older versions of libusnic_verbs actually return 0 when querying for an unknown port. So also check for a magic ID in the returned data to *really* know if the usnic extensions are supported. * Use a union (in the common_verbs area) and memcpy (in the btl) to avoid undefined C type aliasing behavior. * Ensure to memset the function table to 0 if the usnic extensions are not supported. Submitted by Jeff Squyres, reviewed by Dave Goodell. cmr=v1.7.5:reviewer=ompi-rm1.7 This commit was SVN r30935.
Этот коммит содержится в:
родитель
0461e54875
Коммит
fbde50e7cd
@ -30,11 +30,21 @@ void ompi_btl_usnic_ext_init(struct ibv_context *context)
|
|||||||
memset(&ompi_btl_usnic_ext, 0, sizeof(ompi_btl_usnic_ext));
|
memset(&ompi_btl_usnic_ext, 0, sizeof(ompi_btl_usnic_ext));
|
||||||
|
|
||||||
/* See if this context supports the usnic extensions. Do the
|
/* See if this context supports the usnic extensions. Do the
|
||||||
magic query port on port number 42 (which is THE ANSWER) */
|
magic query port on port number 42 (which is THE ANSWER). If
|
||||||
|
it works, we'll get rc==0 and the magic number in the struct
|
||||||
|
will be set. Note, however, that due to a bug in early
|
||||||
|
versions of libusnic_verbs, we *may* get rc==0 even if it
|
||||||
|
doesn't work, which is why we also must check for the magic
|
||||||
|
value, too. */
|
||||||
int rc;
|
int rc;
|
||||||
rc = ibv_query_port(context, 42,
|
struct ibv_port_attr attr;
|
||||||
(struct ibv_port_attr*) &ompi_btl_usnic_ext.qpt);
|
rc = ibv_query_port(context, 42, &attr);
|
||||||
if (0 != rc) {
|
assert(sizeof(ompi_btl_usnic_ext) <= sizeof(attr));
|
||||||
|
memcpy(&ompi_btl_usnic_ext, &attr, sizeof(ompi_btl_usnic_ext));
|
||||||
|
if (0 != rc || USNIC_PORT_QUERY_MAGIC != ompi_btl_usnic_ext.qpt.magic) {
|
||||||
|
/* If the probe fails, we must re-memset() the function
|
||||||
|
pointer block */
|
||||||
|
memset(&ompi_btl_usnic_ext, 0, sizeof(ompi_btl_usnic_ext));
|
||||||
opal_output_verbose(5, USNIC_OUT,
|
opal_output_verbose(5, USNIC_OUT,
|
||||||
"btl:usnic: verbs plugin does not support extensions");
|
"btl:usnic: verbs plugin does not support extensions");
|
||||||
return;
|
return;
|
||||||
@ -50,6 +60,9 @@ void ompi_btl_usnic_ext_init(struct ibv_context *context)
|
|||||||
"btl:usnic: verbs plugin has extension lookup ABI version %d",
|
"btl:usnic: verbs plugin has extension lookup ABI version %d",
|
||||||
ompi_btl_usnic_ext.qpt.lookup_version);
|
ompi_btl_usnic_ext.qpt.lookup_version);
|
||||||
if (1 != ompi_btl_usnic_ext.qpt.lookup_version) {
|
if (1 != ompi_btl_usnic_ext.qpt.lookup_version) {
|
||||||
|
/* If the probe fails, we must re-memset() the function
|
||||||
|
pointer block, because it may/will return junk in the qpt */
|
||||||
|
memset(&ompi_btl_usnic_ext, 0, sizeof(ompi_btl_usnic_ext));
|
||||||
opal_output_verbose(5, USNIC_OUT,
|
opal_output_verbose(5, USNIC_OUT,
|
||||||
"btl:usnic: unrecognized lookup ABI version"
|
"btl:usnic: unrecognized lookup ABI version"
|
||||||
" (I only recognize version 1) "
|
" (I only recognize version 1) "
|
||||||
|
@ -14,13 +14,18 @@
|
|||||||
|
|
||||||
#include <infiniband/verbs.h>
|
#include <infiniband/verbs.h>
|
||||||
|
|
||||||
|
#include "opal_stdint.h"
|
||||||
|
|
||||||
typedef void *(*ompi_btl_usnic_dlsym_fn_t)(const char *name);
|
typedef void *(*ompi_btl_usnic_dlsym_fn_t)(const char *name);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int lookup_version;
|
int lookup_version;
|
||||||
|
uint64_t magic;
|
||||||
ompi_btl_usnic_dlsym_fn_t lookup;
|
ompi_btl_usnic_dlsym_fn_t lookup;
|
||||||
} ompi_btl_usnic_query_port_table_t;
|
} ompi_btl_usnic_query_port_table_t;
|
||||||
|
|
||||||
|
#define USNIC_PORT_QUERY_MAGIC (0x43494e7375534355ULL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tells libusnic_verbs to enable UDP support.
|
* Tells libusnic_verbs to enable UDP support.
|
||||||
*/
|
*/
|
||||||
|
@ -232,6 +232,20 @@ enum {
|
|||||||
USNIC_UNKNOWN
|
USNIC_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* See comment in btl_usnic_ext.c about why we must check the return
|
||||||
|
from the usnic verbs extensions probe for a magic number (which
|
||||||
|
means we must also copy the usnic extension struct and magic number
|
||||||
|
value down here into common/verbs. Bummer). */
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
int lookup_version;
|
||||||
|
uint64_t magic;
|
||||||
|
} qpt;
|
||||||
|
struct ibv_port_attr attr;
|
||||||
|
} port_query_u;
|
||||||
|
|
||||||
|
#define USNIC_PORT_QUERY_MAGIC (0x43494e7375534355ULL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usNIC devices will always return one of three
|
* usNIC devices will always return one of three
|
||||||
* device->transport_type values:
|
* device->transport_type values:
|
||||||
@ -269,10 +283,18 @@ static int usnic_transport(struct ibv_device *device,
|
|||||||
here. */
|
here. */
|
||||||
if (IBV_TRANSPORT_IWARP == device->transport_type) {
|
if (IBV_TRANSPORT_IWARP == device->transport_type) {
|
||||||
int rc;
|
int rc;
|
||||||
struct ibv_port_attr attr;
|
port_query_u u;
|
||||||
rc = ibv_query_port(context, 42, &attr);
|
rc = ibv_query_port(context, 42, &u.attr);
|
||||||
if (0 == rc) {
|
/* See comment in btl_usnic_ext.c about why we have to check
|
||||||
return USNIC_UDP;
|
for rc==0 *and* the magic number. */
|
||||||
|
if (0 == rc && USNIC_PORT_QUERY_MAGIC == u.qpt.magic) {
|
||||||
|
/* We only support version 1 of the lookup function in
|
||||||
|
this particular version of Open MPI */
|
||||||
|
if (1 == u.qpt.lookup_version) {
|
||||||
|
return USNIC_UDP;
|
||||||
|
} else {
|
||||||
|
return USNIC_UNKNOWN;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return USNIC_L2;
|
return USNIC_L2;
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user