2008-05-08 18:38:14 +04:00
|
|
|
#include "ompi_config.h"
|
2008-05-13 20:01:58 +04:00
|
|
|
#include <infiniband/verbs.h>
|
2008-05-11 15:58:02 +04:00
|
|
|
#if OMPI_HAVE_RDMACM
|
2008-05-08 18:38:14 +04:00
|
|
|
|
|
|
|
#include <rdma/rdma_cma.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
#include "opal/util/argv.h"
|
2008-05-13 22:34:22 +04:00
|
|
|
#include "opal/util/if.h"
|
2008-05-08 18:38:14 +04:00
|
|
|
|
|
|
|
#include "connect/connect.h"
|
|
|
|
#include "btl_openib_endpoint.h"
|
|
|
|
#include "btl_openib_iwarp.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The cruft below maintains the linked list of rdma ipv4 addresses and their
|
|
|
|
* associated rdma device names and device port numbers.
|
|
|
|
*/
|
|
|
|
struct rdma_addr_list {
|
|
|
|
opal_list_item_t super;
|
|
|
|
uint32_t addr;
|
|
|
|
uint32_t subnet;
|
|
|
|
char addr_str[16];
|
|
|
|
char dev_name[IBV_SYSFS_NAME_MAX];
|
|
|
|
uint8_t dev_port;
|
|
|
|
};
|
|
|
|
typedef struct rdma_addr_list rdma_addr_list_t;
|
|
|
|
|
|
|
|
static OBJ_CLASS_INSTANCE(rdma_addr_list_t, opal_list_item_t,
|
|
|
|
NULL, NULL);
|
|
|
|
static opal_list_t myaddrs;
|
|
|
|
|
|
|
|
uint64_t get_iwarp_subnet_id(struct ibv_device *ib_dev)
|
|
|
|
{
|
|
|
|
opal_list_item_t *item;
|
|
|
|
|
|
|
|
for (item = opal_list_get_first(&myaddrs);
|
|
|
|
item != opal_list_get_end(&myaddrs);
|
|
|
|
item = opal_list_get_next(item)) {
|
|
|
|
struct rdma_addr_list *addr = (struct rdma_addr_list *)item;
|
|
|
|
if (!strcmp(addr->dev_name, ib_dev->name)) {
|
|
|
|
return addr->subnet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t rdma_get_ipv4addr(struct ibv_context *verbs, uint8_t port)
|
|
|
|
{
|
|
|
|
opal_list_item_t *item;
|
|
|
|
|
|
|
|
for (item = opal_list_get_first(&myaddrs);
|
|
|
|
item != opal_list_get_end(&myaddrs);
|
|
|
|
item = opal_list_get_next(item)) {
|
|
|
|
struct rdma_addr_list *addr = (struct rdma_addr_list *)item;
|
|
|
|
if (!strcmp(addr->dev_name, verbs->device->name) &&
|
|
|
|
port == addr->dev_port) {
|
|
|
|
return addr->addr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int dev_specified(char *name, int port)
|
|
|
|
{
|
|
|
|
char **list;
|
|
|
|
|
|
|
|
if (NULL != mca_btl_openib_component.if_include) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
list = opal_argv_split(mca_btl_openib_component.if_include, ',');
|
|
|
|
for (i = 0; NULL != list[i]; i++) {
|
|
|
|
char **temp = opal_argv_split(list[i], ':');
|
|
|
|
if (0 == strcmp(name, temp[0]) &&
|
|
|
|
(NULL == temp[1] || port == atoi(temp[1]))) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL != mca_btl_openib_component.if_exclude) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
list = opal_argv_split(mca_btl_openib_component.if_exclude, ',');
|
|
|
|
for (i = 0; NULL != list[i]; i++) {
|
|
|
|
char **temp = opal_argv_split(list[i], ':');
|
|
|
|
if (0 == strcmp(name, temp[0]) &&
|
|
|
|
(NULL == temp[1] || port == atoi(temp[1]))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-13 22:34:22 +04:00
|
|
|
static int add_rdma_addr(struct sockaddr *ipaddr, uint32_t netmask)
|
2008-05-08 18:38:14 +04:00
|
|
|
{
|
|
|
|
struct sockaddr_in *sinp;
|
|
|
|
struct rdma_cm_id *cm_id;
|
|
|
|
struct rdma_event_channel *ch;
|
|
|
|
int rc = OMPI_SUCCESS;
|
|
|
|
struct rdma_addr_list *myaddr;
|
|
|
|
|
|
|
|
ch = rdma_create_event_channel();
|
|
|
|
if (NULL == ch) {
|
|
|
|
BTL_ERROR(("failed creating event channel"));
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
goto out1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = rdma_create_id(ch, &cm_id, NULL, RDMA_PS_TCP);
|
|
|
|
if (rc) {
|
|
|
|
BTL_ERROR(("rdma_create_id returned %d", rc));
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
goto out2;
|
|
|
|
}
|
|
|
|
|
2008-05-13 22:34:22 +04:00
|
|
|
rc = rdma_bind_addr(cm_id, ipaddr);
|
2008-05-08 18:38:14 +04:00
|
|
|
if (rc) {
|
|
|
|
rc = OMPI_SUCCESS;
|
|
|
|
goto out3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cm_id->verbs ||
|
2008-05-13 22:34:22 +04:00
|
|
|
0 == ((struct sockaddr_in *)ipaddr)->sin_addr.s_addr ||
|
2008-05-08 18:38:14 +04:00
|
|
|
dev_specified(cm_id->verbs->device->name, cm_id->port_num)) {
|
|
|
|
goto out3;
|
|
|
|
}
|
|
|
|
|
|
|
|
myaddr = OBJ_NEW(rdma_addr_list_t);
|
|
|
|
if (NULL == myaddr) {
|
|
|
|
BTL_ERROR(("malloc failed!"));
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
goto out3;
|
|
|
|
}
|
|
|
|
|
2008-05-13 22:34:22 +04:00
|
|
|
sinp = (struct sockaddr_in *)ipaddr;
|
2008-05-08 18:38:14 +04:00
|
|
|
myaddr->addr = sinp->sin_addr.s_addr;
|
2008-05-13 22:34:22 +04:00
|
|
|
myaddr->subnet = myaddr->addr & netmask;
|
2008-05-08 18:38:14 +04:00
|
|
|
inet_ntop(sinp->sin_family, &sinp->sin_addr,
|
|
|
|
myaddr->addr_str, sizeof myaddr->addr_str);
|
|
|
|
memcpy(myaddr->dev_name, cm_id->verbs->device->name, IBV_SYSFS_NAME_MAX);
|
|
|
|
myaddr->dev_port = cm_id->port_num;
|
|
|
|
BTL_VERBOSE(("adding addr %s dev %s port %d to rdma_addr_list",
|
|
|
|
myaddr->addr_str, myaddr->dev_name, myaddr->dev_port));
|
|
|
|
|
|
|
|
opal_list_append(&myaddrs, &(myaddr->super));
|
|
|
|
|
|
|
|
out3:
|
|
|
|
rdma_destroy_id(cm_id);
|
|
|
|
out2:
|
|
|
|
rdma_destroy_event_channel(ch);
|
|
|
|
out1:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int build_rdma_addr_list(void)
|
|
|
|
{
|
2008-05-13 22:34:22 +04:00
|
|
|
int rc, i;
|
2008-05-08 18:38:14 +04:00
|
|
|
|
|
|
|
OBJ_CONSTRUCT(&myaddrs, opal_list_t);
|
|
|
|
|
2008-05-13 22:34:22 +04:00
|
|
|
for (i = opal_ifbegin(); i < opal_ifcount(); i = opal_ifnext(i)) {
|
|
|
|
struct sockaddr ipaddr;
|
|
|
|
uint32_t netmask;
|
|
|
|
|
|
|
|
opal_ifindextoaddr(i, &ipaddr, sizeof(struct sockaddr));
|
|
|
|
opal_ifindextomask(i, &netmask, sizeof(uint32_t));
|
2008-05-08 18:38:14 +04:00
|
|
|
|
2008-05-13 22:34:22 +04:00
|
|
|
if (ipaddr.sa_family == AF_INET) {
|
|
|
|
rc = add_rdma_addr(&ipaddr, netmask);
|
2008-05-08 18:38:14 +04:00
|
|
|
if (OMPI_SUCCESS != rc) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_rdma_addr_list(void)
|
|
|
|
{
|
|
|
|
opal_list_item_t *item;
|
|
|
|
|
|
|
|
if (0 != opal_list_get_size(&myaddrs)) {
|
|
|
|
for (item = opal_list_get_first(&myaddrs);
|
|
|
|
item != opal_list_get_end(&myaddrs);
|
|
|
|
item = opal_list_get_next(item)) {
|
|
|
|
opal_list_remove_item(&myaddrs, item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline uint64_t get_iwarp_subnet_id(struct ibv_device *ib_dev) {return 0;}
|
|
|
|
static inline uint32_t rdma_get_ipv4addr(struct ibv_context *verbs, uint8_t port) {return 0;}
|
|
|
|
static inline int build_rdma_addr_list(void) {return 0;}
|
|
|
|
static inline void free_rdma_addr_list(void) {}
|
|
|
|
#endif
|