Commit a7ca1f00 authored by Sean Hefty's avatar Sean Hefty Committed by Roland Dreier

RDMA/ucma: Add option to manually set IB path

Export rdma_set_ib_paths to user space to allow applications to
manually set the IB path used for connections.  This allows
alternative ways for a user space application or library to obtain
path record information, including retrieving path information
from cached data, avoiding direct interaction with the IB SA.
The IB SA is a single, centralized entity that can limit scaling
on large clusters running MPI applications.

Future changes to the rdma cm can expand on this framework to
support the full range of features allowed by the IB CM, such as
separate forward and reverse paths and APM.
Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Reviewed-By: default avatarJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 91d3f9ba
...@@ -604,6 +604,12 @@ retry: ...@@ -604,6 +604,12 @@ retry:
return ret ? ret : id; return ret ? ret : id;
} }
void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
{
ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
}
EXPORT_SYMBOL(ib_sa_unpack_path);
static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
int status, int status,
struct ib_sa_mad *mad) struct ib_sa_mad *mad)
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <rdma/rdma_user_cm.h> #include <rdma/rdma_user_cm.h>
#include <rdma/ib_marshall.h> #include <rdma/ib_marshall.h>
#include <rdma/rdma_cm.h> #include <rdma/rdma_cm.h>
#include <rdma/rdma_cm_ib.h>
MODULE_AUTHOR("Sean Hefty"); MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
...@@ -812,6 +813,51 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname, ...@@ -812,6 +813,51 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname,
return ret; return ret;
} }
static int ucma_set_ib_path(struct ucma_context *ctx,
struct ib_path_rec_data *path_data, size_t optlen)
{
struct ib_sa_path_rec sa_path;
struct rdma_cm_event event;
int ret;
if (optlen % sizeof(*path_data))
return -EINVAL;
for (; optlen; optlen -= sizeof(*path_data), path_data++) {
if (path_data->flags == (IB_PATH_GMP | IB_PATH_PRIMARY |
IB_PATH_BIDIRECTIONAL))
break;
}
if (!optlen)
return -EINVAL;
ib_sa_unpack_path(path_data->path_rec, &sa_path);
ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1);
if (ret)
return ret;
memset(&event, 0, sizeof event);
event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
return ucma_event_handler(ctx->cm_id, &event);
}
static int ucma_set_option_ib(struct ucma_context *ctx, int optname,
void *optval, size_t optlen)
{
int ret;
switch (optname) {
case RDMA_OPTION_IB_PATH:
ret = ucma_set_ib_path(ctx, optval, optlen);
break;
default:
ret = -ENOSYS;
}
return ret;
}
static int ucma_set_option_level(struct ucma_context *ctx, int level, static int ucma_set_option_level(struct ucma_context *ctx, int level,
int optname, void *optval, size_t optlen) int optname, void *optval, size_t optlen)
{ {
...@@ -821,6 +867,9 @@ static int ucma_set_option_level(struct ucma_context *ctx, int level, ...@@ -821,6 +867,9 @@ static int ucma_set_option_level(struct ucma_context *ctx, int level,
case RDMA_OPTION_ID: case RDMA_OPTION_ID:
ret = ucma_set_option_id(ctx, optname, optval, optlen); ret = ucma_set_option_id(ctx, optname, optval, optlen);
break; break;
case RDMA_OPTION_IB:
ret = ucma_set_option_ib(ctx, optname, optval, optlen);
break;
default: default:
ret = -ENOSYS; ret = -ENOSYS;
} }
......
...@@ -379,4 +379,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num, ...@@ -379,4 +379,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
struct ib_sa_path_rec *rec, struct ib_sa_path_rec *rec,
struct ib_ah_attr *ah_attr); struct ib_ah_attr *ah_attr);
/**
* ib_sa_unpack_path - Convert a path record from MAD format to struct
* ib_sa_path_rec.
*/
void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec);
#endif /* IB_SA_H */ #endif /* IB_SA_H */
...@@ -35,6 +35,22 @@ ...@@ -35,6 +35,22 @@
#include <linux/types.h> #include <linux/types.h>
enum {
IB_PATH_GMP = 1,
IB_PATH_PRIMARY = (1<<1),
IB_PATH_ALTERNATE = (1<<2),
IB_PATH_OUTBOUND = (1<<3),
IB_PATH_INBOUND = (1<<4),
IB_PATH_INBOUND_REVERSE = (1<<5),
IB_PATH_BIDIRECTIONAL = IB_PATH_OUTBOUND | IB_PATH_INBOUND_REVERSE
};
struct ib_path_rec_data {
__u32 flags;
__u32 reserved;
__u32 path_rec[16];
};
struct ib_user_path_rec { struct ib_user_path_rec {
__u8 dgid[16]; __u8 dgid[16];
__u8 sgid[16]; __u8 sgid[16];
......
...@@ -215,12 +215,14 @@ struct rdma_ucm_event_resp { ...@@ -215,12 +215,14 @@ struct rdma_ucm_event_resp {
/* Option levels */ /* Option levels */
enum { enum {
RDMA_OPTION_ID = 0 RDMA_OPTION_ID = 0,
RDMA_OPTION_IB = 1
}; };
/* Option details */ /* Option details */
enum { enum {
RDMA_OPTION_ID_TOS = 0 RDMA_OPTION_ID_TOS = 0,
RDMA_OPTION_IB_PATH = 1
}; };
struct rdma_ucm_set_option { struct rdma_ucm_set_option {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment