* [PATCH 2/2] Fix a typo in PTP_1588_CLOCK_PCH Kconfig help info.
From: Haicheng Li @ 2012-09-25 0:24 UTC (permalink / raw)
To: David S. Miller, netdev
Cc: Takahiroi Shimizu, linux-kernel@vger.kernel.org, haicheng.lee
In-Reply-To: <50600A49.7040902@linux.intel.com>
From 5911413366d37aafcc19ddfc9c0f2db31855431e Mon Sep 17 00:00:00 2001
From: Haicheng Li <haicheng.li@linux.intel.com>
Date: Mon, 24 Sep 2012 15:55:27 +0800
Subject: [PATCH 2/2] Fix a typo in PTP_1588_CLOCK_PCH Kconfig help info.
Signed-off-by: Haicheng Li <haicheng.lee@gmail.com>
---
drivers/ptp/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index ffdf712..82c4a26 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -87,6 +87,6 @@ config PTP_1588_CLOCK_PCH
SO_TIMESTAMPING API.
To compile this driver as a module, choose M here: the module
- will be called ptp_pch.
+ will be called by pch_ptp.
endmenu
--
1.7.1
^ permalink raw reply related
* [PATCH 1/2] Fix build error caused by broken PCH_PTP module dependency.
From: Haicheng Li @ 2012-09-25 0:23 UTC (permalink / raw)
To: Haicheng Li, David S. Miller, netdev
Cc: Takahiroi Shimizu, linux-kernel@vger.kernel.org, haicheng.lee
In-Reply-To: <506009A4.8000202@linux.intel.com>
From 898e3214b3406c620571cedf704719784b0df049 Mon Sep 17 00:00:00 2001
From: Haicheng Li <haicheng.li@linux.intel.com>
Date: Mon, 24 Sep 2012 15:52:30 +0800
Subject: [PATCH 1/2] Fix build error caused by broken PCH_PTP module dependency.
The .config is:
CONFIG_PCH_GBE=y
CONFIG_PCH_PTP=y
CONFIG_PTP_1588_CLOCK=m
The build error:
drivers/built-in.o: In function `pch_tx_timestamp':
.../pch_gbe_main.c:215: undefined reference to `pch_ch_event_read'
.../pch_gbe_main.c:225: undefined reference to `pch_tx_snap_read'
.../pch_gbe_main.c:231: undefined reference to `pch_ch_event_write'
.../pch_gbe_main.c:170: undefined reference to `pch_ch_event_read'
.../pch_gbe_main.c:175: undefined reference to `pch_src_uuid_lo_read'
.../pch_gbe_main.c:176: undefined reference to `pch_src_uuid_hi_read'
.../pch_gbe_main.c:190: undefined reference to `pch_ch_event_write'
.../pch_gbe_main.c:184: undefined reference to `pch_rx_snap_read'
.../pch_gbe_main.c:267: undefined reference to `pch_ch_control_write'
.../pch_gbe_main.c:271: undefined reference to `pch_ch_control_write'
.../pch_gbe_main.c:275: undefined reference to `pch_ch_control_write'
.../pch_gbe_main.c:281: undefined reference to `pch_ch_control_write'
.../pch_gbe_main.c:283: undefined reference to `pch_set_station_address'
.../pch_gbe_main.c:290: undefined reference to `pch_ch_event_write'
Signed-off-by: Haicheng Li <haicheng.lee@gmail.com>
---
drivers/net/ethernet/oki-semi/pch_gbe/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
index bce0164..6c8aed4 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
@@ -26,7 +26,7 @@ if PCH_GBE
config PCH_PTP
bool "PCH PTP clock support"
default n
- depends on PTP_1588_CLOCK_PCH
+ depends on PTP_1588_CLOCK_PCH = PCH_GBE
---help---
Say Y here if you want to use Precision Time Protocol (PTP) in the
driver. PTP is a method to precisely synchronize distributed clocks
--
1.7.1
^ permalink raw reply related
* [PATCH 10/26 v3] rdma/cm: Add support for AF_IB to rdma_resolve_addr
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Allow the user to specify the remote address using AF_IB format.
When AF_IB is used, the remote address simply needs to be recorded,
and no resolution using ARP is done. The local address may still
need to be matched with a local IB device.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 106 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 100 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index fa4ac4f..9d37c2f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -433,6 +433,61 @@ out:
return ret;
}
+/*
+ * Select the source IB device and address to reach the destination IB address.
+ */
+static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
+{
+ struct cma_device *cma_dev, *cur_dev;
+ struct sockaddr_ib *addr;
+ union ib_gid gid, sgid, *dgid;
+ u16 pkey, index;
+ u8 port, p;
+ int i;
+
+ cma_dev = NULL;
+ addr = (struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr;
+ dgid = (union ib_gid *) &addr->sib_addr;
+ pkey = ntohs(addr->sib_pkey);
+
+ list_for_each_entry(cur_dev, &dev_list, list) {
+ if (rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB)
+ continue;
+
+ for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
+ if (ib_find_cached_pkey(cur_dev->device, p, pkey, &index))
+ continue;
+
+ for (i = 0; !ib_get_cached_gid(cur_dev->device, p, i, &gid); i++) {
+ if (!memcmp(&gid, dgid, sizeof(gid))) {
+ cma_dev = cur_dev;
+ sgid = gid;
+ port = p;
+ goto found;
+ }
+
+ if (!cma_dev && (gid.global.subnet_prefix ==
+ dgid->global.subnet_prefix)) {
+ cma_dev = cur_dev;
+ sgid = gid;
+ port = p;
+ }
+ }
+ }
+ }
+
+ if (!cma_dev)
+ return -ENODEV;
+
+found:
+ cma_attach_to_dev(id_priv, cma_dev);
+ id_priv->id.port_num = port;
+ addr = (struct sockaddr_ib *) &id_priv->id.route.addr.src_addr;
+ memcpy(&addr->sib_addr, &sgid, sizeof sgid);
+ cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr);
+ return 0;
+}
+
static void cma_deref_id(struct rdma_id_private *id_priv)
{
if (atomic_dec_and_test(&id_priv->refcount))
@@ -2091,14 +2146,48 @@ err:
return ret;
}
+static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
+{
+ struct cma_work *work;
+ int ret;
+
+ work = kzalloc(sizeof *work, GFP_KERNEL);
+ if (!work)
+ return -ENOMEM;
+
+ if (!id_priv->cma_dev) {
+ ret = cma_resolve_ib_dev(id_priv);
+ if (ret)
+ goto err;
+ }
+
+ rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, (union ib_gid *)
+ &(((struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr)->sib_addr));
+
+ work->id = id_priv;
+ INIT_WORK(&work->work, cma_work_handler);
+ work->old_state = RDMA_CM_ADDR_QUERY;
+ work->new_state = RDMA_CM_ADDR_RESOLVED;
+ work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
+ queue_work(cma_wq, &work->work);
+ return 0;
+err:
+ kfree(work);
+ return ret;
+}
+
static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
struct sockaddr *dst_addr)
{
if (!src_addr || !src_addr->sa_family) {
src_addr = (struct sockaddr *) &id->route.addr.src_addr;
- if ((src_addr->sa_family = dst_addr->sa_family) == AF_INET6) {
+ src_addr->sa_family = dst_addr->sa_family;
+ if (dst_addr->sa_family == AF_INET6) {
((struct sockaddr_in6 *) src_addr)->sin6_scope_id =
((struct sockaddr_in6 *) dst_addr)->sin6_scope_id;
+ } else if (dst_addr->sa_family == AF_IB) {
+ ((struct sockaddr_ib *) src_addr)->sib_pkey =
+ ((struct sockaddr_ib *) dst_addr)->sib_pkey;
}
}
return rdma_bind_addr(id, src_addr);
@@ -2125,12 +2214,17 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
atomic_inc(&id_priv->refcount);
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
- if (cma_any_addr(dst_addr))
+ if (cma_any_addr(dst_addr)) {
ret = cma_resolve_loopback(id_priv);
- else
- ret = rdma_resolve_ip(&addr_client, cma_src_addr(id_priv),
- dst_addr, &id->route.addr.dev_addr,
- timeout_ms, addr_handler, id_priv);
+ } else {
+ if (dst_addr->sa_family == AF_IB) {
+ ret = cma_resolve_ib_addr(id_priv);
+ } else {
+ ret = rdma_resolve_ip(&addr_client, cma_src_addr(id_priv),
+ dst_addr, &id->route.addr.dev_addr,
+ timeout_ms, addr_handler, id_priv);
+ }
+ }
if (ret)
goto err;
^ permalink raw reply related
* [PATCH 23/26 v3] rdma/ucm: Allow user space to pass AF_IB into resolve
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Allow user space applications to call resolve_addr using
AF_IB. To support sockaddr_ib, we need to define a new
structure capable of handling the larger address size.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 30 +++++++++++++++++++++++++++++-
include/rdma/rdma_user_cm.h | 13 ++++++++++++-
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index d23bc1bf..ecbe404 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -594,6 +594,33 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,
return ret;
}
+static ssize_t ucma_resolve_addr(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_resolve_addr cmd;
+ struct sockaddr *src, *dst;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ src = (struct sockaddr *) &cmd.src_addr;
+ dst = (struct sockaddr *) &cmd.dst_addr;
+ if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
+ !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
+ return -EINVAL;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+ ucma_put_ctx(ctx);
+ return ret;
+}
+
static ssize_t ucma_resolve_route(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -1438,7 +1465,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
[RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
[RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
[RDMA_USER_CM_CMD_QUERY] = ucma_query,
- [RDMA_USER_CM_CMD_BIND] = ucma_bind
+ [RDMA_USER_CM_CMD_BIND] = ucma_bind,
+ [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index cae3e27..b731b5e 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -63,7 +63,8 @@ enum {
RDMA_USER_CM_CMD_LEAVE_MCAST,
RDMA_USER_CM_CMD_MIGRATE_ID,
RDMA_USER_CM_CMD_QUERY,
- RDMA_USER_CM_CMD_BIND
+ RDMA_USER_CM_CMD_BIND,
+ RDMA_USER_CM_CMD_RESOLVE_ADDR
};
/*
@@ -117,6 +118,16 @@ struct rdma_ucm_resolve_ip {
__u32 timeout_ms;
};
+struct rdma_ucm_resolve_addr {
+ __u32 id;
+ __u32 timeout_ms;
+ __u16 src_size;
+ __u16 dst_size;
+ __u32 reserved;
+ struct sockaddr_storage src_addr;
+ struct sockaddr_storage dst_addr;
+};
+
struct rdma_ucm_resolve_route {
__u32 id;
__u32 timeout_ms;
^ permalink raw reply related
* [PATCH 13/26 v3] rdma/cm: Expose private data when using AF_IB
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
If the source or destination address is AF_IB, then do not
reserve a portion of the private data in the IB CM REQ or SIDR
REQ messages for the cma header. Instead, all private data
should be exported to the user. When AF_IB is used, the
rdma cm does not have sufficient information to fill in the
cma header. Additionally, this will be necessary to support
any IB connection through the rdma cm interface,
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 24 ++++++++++--------------
1 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 4e205db..1264e97 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -907,14 +907,10 @@ static void cma_save_net_info(struct rdma_addr *addr,
}
}
-static inline int cma_user_data_offset(enum rdma_port_space ps)
+static inline int cma_user_data_offset(struct rdma_id_private *id_priv)
{
- switch (ps) {
- case RDMA_PS_SDP:
- return 0;
- default:
- return sizeof(struct cma_hdr);
- }
+ return (cma_family(id_priv) == AF_IB || id_priv->id.ps == RDMA_PS_SDP) ?
+ 0 : sizeof(struct cma_hdr);
}
static void cma_cancel_route(struct rdma_id_private *id_priv)
@@ -1310,7 +1306,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
return -ECONNABORTED;
memset(&event, 0, sizeof event);
- offset = cma_user_data_offset(listen_id->id.ps);
+ offset = cma_user_data_offset(listen_id);
event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) {
conn_id = cma_new_udp_id(&listen_id->id, ib_event);
@@ -2637,7 +2633,7 @@ static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv)
cma_hdr->port = src4->sin_port;
break;
}
- } else {
+ } else if (cma_family(id_priv) == AF_INET6) {
struct sockaddr_in6 *src6, *dst6;
src6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
@@ -2735,10 +2731,10 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
{
struct ib_cm_sidr_req_param req;
struct ib_cm_id *id;
- int ret;
+ int offset, ret;
- req.private_data_len = sizeof(struct cma_hdr) +
- conn_param->private_data_len;
+ offset = cma_user_data_offset(id_priv);
+ req.private_data_len = offset + conn_param->private_data_len;
if (req.private_data_len < conn_param->private_data_len)
return -EINVAL;
@@ -2747,7 +2743,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
return -ENOMEM;
if (conn_param->private_data && conn_param->private_data_len)
- memcpy((void *) req.private_data + sizeof(struct cma_hdr),
+ memcpy((void *) req.private_data + offset,
conn_param->private_data, conn_param->private_data_len);
ret = cma_format_hdr((void *) req.private_data, id_priv);
@@ -2787,7 +2783,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
int offset, ret;
memset(&req, 0, sizeof req);
- offset = cma_user_data_offset(id_priv->id.ps);
+ offset = cma_user_data_offset(id_priv);
req.private_data_len = offset + conn_param->private_data_len;
if (req.private_data_len < conn_param->private_data_len)
return -EINVAL;
^ permalink raw reply related
* [PATCH 21/26 v3] rdma/ucm: Name changes to indicate only IP addresses supported
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Several commands into the RDMA CM from user space are
restricted to supporting addresses which fit into a sockaddr_in6
structure: bind address, resolve address, and join multicast.
With the addition of AF_IB, we need to support addresses
which are larger than sockaddr_in6. This will be done by
adding new commands that exchange address information using
sockaddr_storage. However, to support existing applications,
we maintain the current commands and structures, but rename
them to indicate that they only support IPv4 and v6 addresses.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 60 ++++++++++++++++++++--------------------
include/rdma/rdma_user_cm.h | 12 ++++----
2 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 199b076..6fc36ba 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -529,10 +529,10 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf,
return ret;
}
-static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf,
+static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,
int in_len, int out_len)
{
- struct rdma_ucm_bind_addr cmd;
+ struct rdma_ucm_bind_ip cmd;
struct ucma_context *ctx;
int ret;
@@ -548,11 +548,11 @@ static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf,
return ret;
}
-static ssize_t ucma_resolve_addr(struct ucma_file *file,
- const char __user *inbuf,
- int in_len, int out_len)
+static ssize_t ucma_resolve_ip(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
{
- struct rdma_ucm_resolve_addr cmd;
+ struct rdma_ucm_resolve_ip cmd;
struct ucma_context *ctx;
int ret;
@@ -1193,11 +1193,11 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
return ret;
}
-static ssize_t ucma_join_multicast(struct ucma_file *file,
- const char __user *inbuf,
- int in_len, int out_len)
+static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
{
- struct rdma_ucm_join_mcast cmd;
+ struct rdma_ucm_join_ip_mcast cmd;
struct rdma_ucm_create_id_resp resp;
struct ucma_context *ctx;
struct ucma_multicast *mc;
@@ -1394,26 +1394,26 @@ file_put:
static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len) = {
- [RDMA_USER_CM_CMD_CREATE_ID] = ucma_create_id,
- [RDMA_USER_CM_CMD_DESTROY_ID] = ucma_destroy_id,
- [RDMA_USER_CM_CMD_BIND_ADDR] = ucma_bind_addr,
- [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr,
- [RDMA_USER_CM_CMD_RESOLVE_ROUTE]= ucma_resolve_route,
- [RDMA_USER_CM_CMD_QUERY_ROUTE] = ucma_query_route,
- [RDMA_USER_CM_CMD_CONNECT] = ucma_connect,
- [RDMA_USER_CM_CMD_LISTEN] = ucma_listen,
- [RDMA_USER_CM_CMD_ACCEPT] = ucma_accept,
- [RDMA_USER_CM_CMD_REJECT] = ucma_reject,
- [RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect,
- [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr,
- [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event,
- [RDMA_USER_CM_CMD_GET_OPTION] = NULL,
- [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option,
- [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
- [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast,
- [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
- [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
- [RDMA_USER_CM_CMD_QUERY] = ucma_query
+ [RDMA_USER_CM_CMD_CREATE_ID] = ucma_create_id,
+ [RDMA_USER_CM_CMD_DESTROY_ID] = ucma_destroy_id,
+ [RDMA_USER_CM_CMD_BIND_IP] = ucma_bind_ip,
+ [RDMA_USER_CM_CMD_RESOLVE_IP] = ucma_resolve_ip,
+ [RDMA_USER_CM_CMD_RESOLVE_ROUTE] = ucma_resolve_route,
+ [RDMA_USER_CM_CMD_QUERY_ROUTE] = ucma_query_route,
+ [RDMA_USER_CM_CMD_CONNECT] = ucma_connect,
+ [RDMA_USER_CM_CMD_LISTEN] = ucma_listen,
+ [RDMA_USER_CM_CMD_ACCEPT] = ucma_accept,
+ [RDMA_USER_CM_CMD_REJECT] = ucma_reject,
+ [RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect,
+ [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr,
+ [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event,
+ [RDMA_USER_CM_CMD_GET_OPTION] = NULL,
+ [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option,
+ [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
+ [RDMA_USER_CM_CMD_JOIN_IP_MCAST] = ucma_join_ip_multicast,
+ [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
+ [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
+ [RDMA_USER_CM_CMD_QUERY] = ucma_query
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index b0634d4..bfb2ca7 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -45,8 +45,8 @@
enum {
RDMA_USER_CM_CMD_CREATE_ID,
RDMA_USER_CM_CMD_DESTROY_ID,
- RDMA_USER_CM_CMD_BIND_ADDR,
- RDMA_USER_CM_CMD_RESOLVE_ADDR,
+ RDMA_USER_CM_CMD_BIND_IP,
+ RDMA_USER_CM_CMD_RESOLVE_IP,
RDMA_USER_CM_CMD_RESOLVE_ROUTE,
RDMA_USER_CM_CMD_QUERY_ROUTE,
RDMA_USER_CM_CMD_CONNECT,
@@ -59,7 +59,7 @@ enum {
RDMA_USER_CM_CMD_GET_OPTION,
RDMA_USER_CM_CMD_SET_OPTION,
RDMA_USER_CM_CMD_NOTIFY,
- RDMA_USER_CM_CMD_JOIN_MCAST,
+ RDMA_USER_CM_CMD_JOIN_IP_MCAST,
RDMA_USER_CM_CMD_LEAVE_MCAST,
RDMA_USER_CM_CMD_MIGRATE_ID,
RDMA_USER_CM_CMD_QUERY
@@ -96,13 +96,13 @@ struct rdma_ucm_destroy_id_resp {
__u32 events_reported;
};
-struct rdma_ucm_bind_addr {
+struct rdma_ucm_bind_ip {
__u64 response;
struct sockaddr_in6 addr;
__u32 id;
};
-struct rdma_ucm_resolve_addr {
+struct rdma_ucm_resolve_ip {
struct sockaddr_in6 src_addr;
struct sockaddr_in6 dst_addr;
__u32 id;
@@ -216,7 +216,7 @@ struct rdma_ucm_notify {
__u32 event;
};
-struct rdma_ucm_join_mcast {
+struct rdma_ucm_join_ip_mcast {
__u64 response; /* rdma_ucm_create_id_resp */
__u64 uid;
struct sockaddr_in6 addr;
^ permalink raw reply related
* [PATCH 17/26 v3] ib/sa: Export function to pack a path record into wire format
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Allow converting from struct ib_sa_path_rec to the IB defined
SA path record wire format. This will be used to report path
data from the rdma cm into user space.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/sa_query.c | 6 ++++++
include/rdma/ib_sa.h | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index fbbfa24..027c797 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -616,6 +616,12 @@ void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
}
EXPORT_SYMBOL(ib_sa_unpack_path);
+void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute)
+{
+ ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, attribute);
+}
+EXPORT_SYMBOL(ib_sa_pack_path);
+
static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
int status,
struct ib_sa_mad *mad)
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index d44a563..ade03ca 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -385,4 +385,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
*/
void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec);
+/**
+ * ib_sa_pack_path - Conert a path record from struct ib_sa_path_rec
+ * to IB MAD wire format.
+ */
+void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute);
+
#endif /* IB_SA_H */
^ permalink raw reply related
* [PATCH 20/26 v3] rdma/ucm: Add ability to query GID addresses
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Part of address resolution is mapping IP addresses to IB GIDs.
With the changes to support querying larger addresses and more
path records, also provide a way to query IB GIDs after
resolution completes.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 50 ++++++++++++++++++++++++++++++++++++++++
include/rdma/rdma_user_cm.h | 3 ++
2 files changed, 52 insertions(+), 1 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 9b60338..199b076 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -48,6 +48,7 @@
#include <rdma/rdma_cm.h>
#include <rdma/rdma_cm_ib.h>
#include <rdma/ib_addr.h>
+#include <rdma/ib.h>
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -799,6 +800,52 @@ static ssize_t ucma_query_path(struct ucma_context *ctx,
return ret;
}
+static ssize_t ucma_query_gid(struct ucma_context *ctx,
+ void __user *response, int out_len)
+{
+ struct rdma_ucm_query_addr_resp resp;
+ struct sockaddr_ib *addr;
+ int ret = 0;
+
+ if (out_len < sizeof(resp))
+ return -ENOSPC;
+
+ memset(&resp, 0, sizeof resp);
+
+ ucma_query_device_addr(ctx->cm_id, &resp);
+
+ addr = (struct sockaddr_ib *) &resp.src_addr;
+ resp.src_size = sizeof(*addr);
+ if (ctx->cm_id->route.addr.src_addr.ss_family == AF_IB) {
+ memcpy(addr, &ctx->cm_id->route.addr.src_addr, resp.src_size);
+ } else {
+ addr->sib_family = AF_IB;
+ addr->sib_pkey = (__force __be16) resp.pkey;
+ rdma_addr_get_sgid(&ctx->cm_id->route.addr.dev_addr,
+ (union ib_gid *) &addr->sib_addr);
+ addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
+ &ctx->cm_id->route.addr.src_addr);
+ }
+
+ addr = (struct sockaddr_ib *) &resp.dst_addr;
+ resp.dst_size = sizeof(*addr);
+ if (ctx->cm_id->route.addr.dst_addr.ss_family == AF_IB) {
+ memcpy(addr, &ctx->cm_id->route.addr.dst_addr, resp.dst_size);
+ } else {
+ addr->sib_family = AF_IB;
+ addr->sib_pkey = (__force __be16) resp.pkey;
+ rdma_addr_get_dgid(&ctx->cm_id->route.addr.dev_addr,
+ (union ib_gid *) &addr->sib_addr);
+ addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
+ &ctx->cm_id->route.addr.dst_addr);
+ }
+
+ if (copy_to_user(response, &resp, sizeof(resp)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
static ssize_t ucma_query(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -823,6 +870,9 @@ static ssize_t ucma_query(struct ucma_file *file,
case RDMA_USER_CM_QUERY_PATH:
ret = ucma_query_path(ctx, response, out_len);
break;
+ case RDMA_USER_CM_QUERY_GID:
+ ret = ucma_query_gid(ctx, response, out_len);
+ break;
default:
ret = -ENOSYS;
break;
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index effcb75..b0634d4 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -116,7 +116,8 @@ struct rdma_ucm_resolve_route {
enum {
RDMA_USER_CM_QUERY_ADDR,
- RDMA_USER_CM_QUERY_PATH
+ RDMA_USER_CM_QUERY_PATH,
+ RDMA_USER_CM_QUERY_GID
};
struct rdma_ucm_query {
^ permalink raw reply related
* [PATCH 3/26 v3] ib/addr: Add AF_IB support to ip_addr_size
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Add support for AF_IB to ip_addr_size, and rename the function
to account for the change. Give the compiler more control over
whether the call should be inline or not by moving the definition
into the .c file, removing the static inline, and exporting it.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/addr.c | 20 ++++++++++++++++++--
drivers/infiniband/core/cma.c | 12 ++++++------
include/rdma/ib_addr.h | 6 +-----
3 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 6ef660c..c7998b9 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -45,6 +45,7 @@
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <rdma/ib_addr.h>
+#include <rdma/ib.h>
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("IB Address Translation");
@@ -70,6 +71,21 @@ static LIST_HEAD(req_list);
static DECLARE_DELAYED_WORK(work, process_req);
static struct workqueue_struct *addr_wq;
+int rdma_addr_size(struct sockaddr *addr)
+{
+ switch (addr->sa_family) {
+ case AF_INET:
+ return sizeof(struct sockaddr_in);
+ case AF_INET6:
+ return sizeof(struct sockaddr_in6);
+ case AF_IB:
+ return sizeof(struct sockaddr_ib);
+ default:
+ return 0;
+ }
+}
+EXPORT_SYMBOL(rdma_addr_size);
+
void rdma_addr_register_client(struct rdma_addr_client *client)
{
atomic_set(&client->refcount, 1);
@@ -371,12 +387,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
goto err;
}
- memcpy(src_in, src_addr, ip_addr_size(src_addr));
+ memcpy(src_in, src_addr, rdma_addr_size(src_addr));
} else {
src_in->sa_family = dst_addr->sa_family;
}
- memcpy(dst_in, dst_addr, ip_addr_size(dst_addr));
+ memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr));
req->addr = addr;
req->callback = callback;
req->context = context;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index e3d2837..af21aa4 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1575,7 +1575,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
dev_id_priv->state = RDMA_CM_ADDR_BOUND;
memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
- ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
+ rdma_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
cma_attach_to_dev(dev_id_priv, cma_dev);
list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
@@ -1979,7 +1979,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
event.status = status;
} else {
memcpy(&id_priv->id.route.addr.src_addr, src_addr,
- ip_addr_size(src_addr));
+ rdma_addr_size(src_addr));
event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
}
@@ -2069,7 +2069,7 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
return -EINVAL;
atomic_inc(&id_priv->refcount);
- memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr));
+ memcpy(&id->route.addr.dst_addr, dst_addr, rdma_addr_size(dst_addr));
if (cma_any_addr(dst_addr))
ret = cma_resolve_loopback(id_priv);
else
@@ -2378,7 +2378,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
goto err1;
}
- memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
+ memcpy(&id->route.addr.src_addr, addr, rdma_addr_size(addr));
ret = cma_get_port(id_priv);
if (ret)
goto err2;
@@ -3149,7 +3149,7 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
if (!mc)
return -ENOMEM;
- memcpy(&mc->addr, addr, ip_addr_size(addr));
+ memcpy(&mc->addr, addr, rdma_addr_size(addr));
mc->context = context;
mc->id_priv = id_priv;
@@ -3194,7 +3194,7 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
id_priv = container_of(id, struct rdma_id_private, id);
spin_lock_irq(&id_priv->lock);
list_for_each_entry(mc, &id_priv->mc_list, list) {
- if (!memcmp(&mc->addr, addr, ip_addr_size(addr))) {
+ if (!memcmp(&mc->addr, addr, rdma_addr_size(addr))) {
list_del(&mc->list);
spin_unlock_irq(&id_priv->lock);
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index 9996539..f3ac0f2 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -102,11 +102,7 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr);
int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
const unsigned char *dst_dev_addr);
-static inline int ip_addr_size(struct sockaddr *addr)
-{
- return addr->sa_family == AF_INET6 ?
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
-}
+int rdma_addr_size(struct sockaddr *addr);
static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr)
{
^ permalink raw reply related
* [PATCH 5/26 v3] rdma/cm: Allow user to specify AF_IB when binding
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Modify rdma_bind_addr to allow the user to specify AF_IB when
binding to a device. AF_IB indicates that the user is not
mapping an IP address to the native IB addressing. (The mapping
may have already been done, or is not needed.)
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 34 ++++++++++++++++++++++++++++------
1 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index f569127..f09450e 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -353,6 +353,27 @@ static int find_gid_port(struct ib_device *device, union ib_gid *gid, u8 port_nu
return -EAGAIN;
}
+static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr)
+{
+ dev_addr->dev_type = ARPHRD_INFINIBAND;
+ rdma_addr_set_sgid(dev_addr, (union ib_gid *) &sib->sib_addr);
+ ib_addr_set_pkey(dev_addr, ntohs(sib->sib_pkey));
+}
+
+static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
+{
+ int ret;
+
+ if (addr->sa_family != AF_IB) {
+ ret = rdma_translate_ip(addr, dev_addr);
+ } else {
+ cma_translate_ib((struct sockaddr_ib *) addr, dev_addr);
+ ret = 0;
+ }
+
+ return ret;
+}
+
static int cma_acquire_dev(struct rdma_id_private *id_priv)
{
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
@@ -1131,8 +1152,8 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
} else {
- ret = rdma_translate_ip((struct sockaddr *) &rt->addr.src_addr,
- &rt->addr.dev_addr);
+ ret = cma_translate_addr((struct sockaddr *) &rt->addr.src_addr,
+ &rt->addr.dev_addr);
if (ret)
goto err;
}
@@ -1171,8 +1192,8 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
ip_ver, port, src, dst);
if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) {
- ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
- &id->route.addr.dev_addr);
+ ret = cma_translate_addr((struct sockaddr *) &id->route.addr.src_addr,
+ &id->route.addr.dev_addr);
if (ret)
goto err;
}
@@ -2422,7 +2443,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
struct rdma_id_private *id_priv;
int ret;
- if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
+ if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 &&
+ addr->sa_family != AF_IB)
return -EAFNOSUPPORT;
id_priv = container_of(id, struct rdma_id_private, id);
@@ -2434,7 +2456,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
goto err1;
if (!cma_any_addr(addr)) {
- ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
+ ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
if (ret)
goto err1;
^ permalink raw reply related
* [PATCH 24/26 v3] rdma/ucm: Allow user space to specify AF_IB when joining multicast
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Allow user space applications to join multicast groups using MGIDs
directly. MGIDs may be passed using AF_IB addresses. Since the
current multicast join command only supports addresses as large as
sockaddr_in6, define a new structure for joining addresses specified
using sockaddr_ib.
Since AF_IB allows the user to specify the qkey when
resolving a remote UD QP address, when joining the multicast
group use the qkey value, if one has been assigned.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 9 +++++--
drivers/infiniband/core/ucma.c | 55 ++++++++++++++++++++++++++++++++--------
include/rdma/rdma_user_cm.h | 12 ++++++++-
3 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 8f9c05f..93f7b5c 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3200,6 +3200,8 @@ static void cma_set_mgid(struct rdma_id_private *id_priv,
0xFF10A01B)) {
/* IPv6 address is an SA assigned MGID. */
memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
+ } else if (addr->sa_family == AF_IB) {
+ memcpy(mgid, &((struct sockaddr_ib *) addr)->sib_addr, sizeof *mgid);
} else if ((addr->sa_family == AF_INET6)) {
ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map);
if (id_priv->id.ps == RDMA_PS_UDP)
@@ -3227,9 +3229,12 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
if (ret)
return ret;
+ ret = cma_set_qkey(id_priv, 0);
+ if (ret)
+ return ret;
+
cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
- if (id_priv->id.ps == RDMA_PS_UDP)
- rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
+ rec.qkey = cpu_to_be32(id_priv->qkey);
rdma_addr_get_sgid(dev_addr, &rec.port_gid);
rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
rec.join_state = 1;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index ecbe404..83e02f0 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1244,23 +1244,23 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
return ret;
}
-static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
- const char __user *inbuf,
- int in_len, int out_len)
+static ssize_t ucma_process_join(struct ucma_file *file,
+ struct rdma_ucm_join_mcast *cmd, int out_len)
{
- struct rdma_ucm_join_ip_mcast cmd;
struct rdma_ucm_create_id_resp resp;
struct ucma_context *ctx;
struct ucma_multicast *mc;
+ struct sockaddr *addr;
int ret;
if (out_len < sizeof(resp))
return -ENOSPC;
- if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
- return -EFAULT;
+ addr = (struct sockaddr *) &cmd->addr;
+ if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
+ return -EINVAL;
- ctx = ucma_get_ctx(file, cmd.id);
+ ctx = ucma_get_ctx(file, cmd->id);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
@@ -1271,14 +1271,14 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
goto err1;
}
- mc->uid = cmd.uid;
- memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
+ mc->uid = cmd->uid;
+ memcpy(&mc->addr, addr, cmd->addr_size);
ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc);
if (ret)
goto err2;
resp.id = mc->id;
- if (copy_to_user((void __user *)(unsigned long)cmd.response,
+ if (copy_to_user((void __user *)(unsigned long) cmd->response,
&resp, sizeof(resp))) {
ret = -EFAULT;
goto err3;
@@ -1303,6 +1303,38 @@ err1:
return ret;
}
+static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_join_ip_mcast cmd;
+ struct rdma_ucm_join_mcast join_cmd;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ join_cmd.response = cmd.response;
+ join_cmd.uid = cmd.uid;
+ join_cmd.id = cmd.id;
+ join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+ join_cmd.reserved = 0;
+ memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
+
+ return ucma_process_join(file, &join_cmd, out_len);
+}
+
+static ssize_t ucma_join_multicast(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_join_mcast cmd;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ return ucma_process_join(file, &cmd, out_len);
+}
+
static ssize_t ucma_leave_multicast(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -1466,7 +1498,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
[RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
[RDMA_USER_CM_CMD_QUERY] = ucma_query,
[RDMA_USER_CM_CMD_BIND] = ucma_bind,
- [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr
+ [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr,
+ [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index b731b5e..bf34156 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -64,7 +64,8 @@ enum {
RDMA_USER_CM_CMD_MIGRATE_ID,
RDMA_USER_CM_CMD_QUERY,
RDMA_USER_CM_CMD_BIND,
- RDMA_USER_CM_CMD_RESOLVE_ADDR
+ RDMA_USER_CM_CMD_RESOLVE_ADDR,
+ RDMA_USER_CM_CMD_JOIN_MCAST
};
/*
@@ -242,6 +243,15 @@ struct rdma_ucm_join_ip_mcast {
__u32 id;
};
+struct rdma_ucm_join_mcast {
+ __u64 response; /* rdma_ucma_create_id_resp */
+ __u64 uid;
+ __u32 id;
+ __u16 addr_size;
+ __u16 reserved;
+ struct sockaddr_storage addr;
+};
+
struct rdma_ucm_get_event {
__u64 response;
};
^ permalink raw reply related
* [PATCH 22/26 v3] rdma/ucm: Allow user space to bind to AF_IB
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Support user space binding to addresses using AF_IB. Since
sockaddr_ib is larger than sockaddr_in6, we need to define
a larger structure when binding using AF_IB. This time we
use sockaddr_storage to cover future cases.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 27 ++++++++++++++++++++++++++-
include/rdma/rdma_user_cm.h | 10 +++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 6fc36ba..d23bc1bf 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -548,6 +548,30 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,
return ret;
}
+static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_bind cmd;
+ struct sockaddr *addr;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ addr = (struct sockaddr *) &cmd.addr;
+ if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
+ return -EINVAL;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ ret = rdma_bind_addr(ctx->cm_id, addr);
+ ucma_put_ctx(ctx);
+ return ret;
+}
+
static ssize_t ucma_resolve_ip(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -1413,7 +1437,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
[RDMA_USER_CM_CMD_JOIN_IP_MCAST] = ucma_join_ip_multicast,
[RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
[RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
- [RDMA_USER_CM_CMD_QUERY] = ucma_query
+ [RDMA_USER_CM_CMD_QUERY] = ucma_query,
+ [RDMA_USER_CM_CMD_BIND] = ucma_bind
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index bfb2ca7..cae3e27 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -62,7 +62,8 @@ enum {
RDMA_USER_CM_CMD_JOIN_IP_MCAST,
RDMA_USER_CM_CMD_LEAVE_MCAST,
RDMA_USER_CM_CMD_MIGRATE_ID,
- RDMA_USER_CM_CMD_QUERY
+ RDMA_USER_CM_CMD_QUERY,
+ RDMA_USER_CM_CMD_BIND
};
/*
@@ -102,6 +103,13 @@ struct rdma_ucm_bind_ip {
__u32 id;
};
+struct rdma_ucm_bind {
+ __u32 id;
+ __u16 addr_size;
+ __u16 reserved;
+ struct sockaddr_storage addr;
+};
+
struct rdma_ucm_resolve_ip {
struct sockaddr_in6 src_addr;
struct sockaddr_in6 dst_addr;
^ permalink raw reply related
* [PATCH 26/26 v3] rdma/cm: Allow enabling reuseaddr in any state
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
The rdma_cm only allows setting reuseaddr if the corresponding
rdma_cm_id is in the idle state. Allow setting this value in
other states. This brings the behavior more inline with
sockets.
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index dbb6d73..08d7b9c 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2266,7 +2266,7 @@ int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse)
id_priv = container_of(id, struct rdma_id_private, id);
spin_lock_irqsave(&id_priv->lock, flags);
- if (id_priv->state == RDMA_CM_IDLE) {
+ if (reuse || id_priv->state == RDMA_CM_IDLE) {
id_priv->reuseaddr = reuse;
ret = 0;
} else {
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 25/26 v3] rdma/cm: Export AF_IB statistics
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Report AF_IB source and destination addresses through
netlink interface.
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 37 ++++++++++---------------------------
1 files changed, 10 insertions(+), 27 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 93f7b5c..dbb6d73 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3637,33 +3637,16 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb)
id_stats->bound_dev_if =
id->route.addr.dev_addr.bound_dev_if;
- if (cma_family(id_priv) == AF_INET) {
- if (ibnl_put_attr(skb, nlh,
- sizeof(struct sockaddr_in),
- cma_src_addr(id_priv),
- RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
- goto out;
- }
- if (ibnl_put_attr(skb, nlh,
- sizeof(struct sockaddr_in),
- cma_dst_addr(id_priv),
- RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
- goto out;
- }
- } else if (cma_family(id_priv) == AF_INET6) {
- if (ibnl_put_attr(skb, nlh,
- sizeof(struct sockaddr_in6),
- cma_src_addr(id_priv),
- RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
- goto out;
- }
- if (ibnl_put_attr(skb, nlh,
- sizeof(struct sockaddr_in6),
- cma_dst_addr(id_priv),
- RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
- goto out;
- }
- }
+ if (ibnl_put_attr(skb, nlh,
+ rdma_addr_size(cma_src_addr(id_priv)),
+ cma_src_addr(id_priv),
+ RDMA_NL_RDMA_CM_ATTR_SRC_ADDR))
+ goto out;
+ if (ibnl_put_attr(skb, nlh,
+ rdma_addr_size(cma_src_addr(id_priv)),
+ cma_dst_addr(id_priv),
+ RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
+ goto out;
id_stats->pid = id_priv->owner;
id_stats->port_space = id->ps;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 15/26 v3] rdma/cm: Only listen on IB devices when using AF_IB
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
If an rdma_cm_id is bound to AF_IB, with a wild card address,
only listen on IB devices.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 13423bb..d7bc654 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1671,6 +1671,10 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
struct rdma_cm_id *id;
int ret;
+ if (cma_family(id_priv) == AF_IB &&
+ rdma_node_get_transport(cma_dev->device->node_type) != RDMA_TRANSPORT_IB)
+ return;
+
id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps,
id_priv->id.qp_type);
if (IS_ERR(id))
^ permalink raw reply related
* [PATCH 18/26 v3] rdma/ucm: Support querying when IB paths are not reversible
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
The current query_route call can return up to two path records.
The assumption being that one is the primary path, with optional
support for an alternate path. In both cases, the paths are
assumed to be reversible and are used to send CM MADs.
With the ability to manually set IB path data, the rdma cm
can eventually be capable of using up to 6 paths per
connection:
forward primary, reverse primary,
forward alternate, reverse alternate,
reversible primary path for CM MADs
reversible alternate path for CM MADs.
(It is unclear at this time if IB routing will complicate this.)
In order to handle more flexible routing topologies, add a new
command to report any number of paths.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 35 +++++++++++++++++++++++++++++++++++
include/rdma/rdma_user_cm.h | 9 ++++++++-
2 files changed, 43 insertions(+), 1 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index b9ce266..9b60338 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -767,6 +767,38 @@ static ssize_t ucma_query_addr(struct ucma_context *ctx,
return ret;
}
+static ssize_t ucma_query_path(struct ucma_context *ctx,
+ void __user *response, int out_len)
+{
+ struct rdma_ucm_query_path_resp *resp;
+ int i, ret = 0;
+
+ if (out_len < sizeof(*resp))
+ return -ENOSPC;
+
+ resp = kzalloc(out_len, GFP_KERNEL);
+ if (!resp)
+ return -ENOMEM;
+
+ resp->num_paths = ctx->cm_id->route.num_paths;
+ for (i = 0, out_len -= sizeof(*resp);
+ i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data);
+ i++, out_len -= sizeof(struct ib_path_rec_data)) {
+
+ resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY |
+ IB_PATH_BIDIRECTIONAL;
+ ib_sa_pack_path(&ctx->cm_id->route.path_rec[i],
+ &resp->path_data[i].path_rec);
+ }
+
+ if (copy_to_user(response, resp,
+ sizeof(*resp) + (i * sizeof(struct ib_path_rec_data))))
+ ret = -EFAULT;
+
+ kfree(resp);
+ return ret;
+}
+
static ssize_t ucma_query(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -788,6 +820,9 @@ static ssize_t ucma_query(struct ucma_file *file,
case RDMA_USER_CM_QUERY_ADDR:
ret = ucma_query_addr(ctx, response, out_len);
break;
+ case RDMA_USER_CM_QUERY_PATH:
+ ret = ucma_query_path(ctx, response, out_len);
+ break;
default:
ret = -ENOSYS;
break;
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index 4037c48..effcb75 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -115,7 +115,8 @@ struct rdma_ucm_resolve_route {
};
enum {
- RDMA_USER_CM_QUERY_ADDR
+ RDMA_USER_CM_QUERY_ADDR,
+ RDMA_USER_CM_QUERY_PATH
};
struct rdma_ucm_query {
@@ -145,6 +146,12 @@ struct rdma_ucm_query_addr_resp {
struct sockaddr_storage dst_addr;
};
+struct rdma_ucm_query_path_resp {
+ __u32 num_paths;
+ __u32 reserved;
+ struct ib_path_rec_data path_data[0];
+};
+
struct rdma_ucm_conn_param {
__u32 qp_num;
__u32 qkey;
^ permalink raw reply related
* [PATCH 16/26 v3] rdma/ucm: Support querying for AF_IB addresses
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
The sockaddr structure for AF_IB is larger than sockaddr_in6.
The rdma cm user space ABI uses the latter to exchange address
information between user space and the kernel.
To support querying for larger addresses, define a new query
command that exchanges data using sockaddr_storage, rather
than sockaddr_in6. Unlike the existing query_route command,
the new command only returns address information. Route
(i.e. path record) data is separated.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/ucma.c | 76 +++++++++++++++++++++++++++++++++++++++-
include/rdma/rdma_user_cm.h | 22 ++++++++++--
2 files changed, 93 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 52c606b..b9ce266 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -47,6 +47,7 @@
#include <rdma/ib_marshall.h>
#include <rdma/rdma_cm.h>
#include <rdma/rdma_cm_ib.h>
+#include <rdma/ib_addr.h>
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -666,7 +667,7 @@ static ssize_t ucma_query_route(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
{
- struct rdma_ucm_query_route cmd;
+ struct rdma_ucm_query cmd;
struct rdma_ucm_query_route_resp resp;
struct ucma_context *ctx;
struct sockaddr *addr;
@@ -726,6 +727,76 @@ out:
return ret;
}
+static void ucma_query_device_addr(struct rdma_cm_id *cm_id,
+ struct rdma_ucm_query_addr_resp *resp)
+{
+ if (!cm_id->device)
+ return;
+
+ resp->node_guid = (__force __u64) cm_id->device->node_guid;
+ resp->port_num = cm_id->port_num;
+ resp->pkey = (__force __u16) cpu_to_be16(
+ ib_addr_get_pkey(&cm_id->route.addr.dev_addr));
+}
+
+static ssize_t ucma_query_addr(struct ucma_context *ctx,
+ void __user *response, int out_len)
+{
+ struct rdma_ucm_query_addr_resp resp;
+ struct sockaddr *addr;
+ int ret = 0;
+
+ if (out_len < sizeof(resp))
+ return -ENOSPC;
+
+ memset(&resp, 0, sizeof resp);
+
+ addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr;
+ resp.src_size = rdma_addr_size(addr);
+ memcpy(&resp.src_addr, addr, resp.src_size);
+
+ addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr;
+ resp.dst_size = rdma_addr_size(addr);
+ memcpy(&resp.dst_addr, addr, resp.dst_size);
+
+ ucma_query_device_addr(ctx->cm_id, &resp);
+
+ if (copy_to_user(response, &resp, sizeof(resp)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static ssize_t ucma_query(struct ucma_file *file,
+ const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_query cmd;
+ struct ucma_context *ctx;
+ void __user *response;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ response = (void __user *)(unsigned long) cmd.response;
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ switch (cmd.option) {
+ case RDMA_USER_CM_QUERY_ADDR:
+ ret = ucma_query_addr(ctx, response, out_len);
+ break;
+ default:
+ ret = -ENOSYS;
+ break;
+ }
+
+ ucma_put_ctx(ctx);
+ return ret;
+}
+
static void ucma_copy_conn_param(struct rdma_cm_id *id,
struct rdma_conn_param *dst,
struct rdma_ucm_conn_param *src)
@@ -1256,7 +1327,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
[RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
[RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast,
[RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
- [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id
+ [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
+ [RDMA_USER_CM_CMD_QUERY] = ucma_query
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index ca8d4d4..4037c48 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -61,7 +61,8 @@ enum {
RDMA_USER_CM_CMD_NOTIFY,
RDMA_USER_CM_CMD_JOIN_MCAST,
RDMA_USER_CM_CMD_LEAVE_MCAST,
- RDMA_USER_CM_CMD_MIGRATE_ID
+ RDMA_USER_CM_CMD_MIGRATE_ID,
+ RDMA_USER_CM_CMD_QUERY
};
/*
@@ -113,10 +114,14 @@ struct rdma_ucm_resolve_route {
__u32 timeout_ms;
};
-struct rdma_ucm_query_route {
+enum {
+ RDMA_USER_CM_QUERY_ADDR
+};
+
+struct rdma_ucm_query {
__u64 response;
__u32 id;
- __u32 reserved;
+ __u32 option;
};
struct rdma_ucm_query_route_resp {
@@ -129,6 +134,17 @@ struct rdma_ucm_query_route_resp {
__u8 reserved[3];
};
+struct rdma_ucm_query_addr_resp {
+ __u64 node_guid;
+ __u8 port_num;
+ __u8 reserved;
+ __u16 pkey;
+ __u16 src_size;
+ __u16 dst_size;
+ struct sockaddr_storage src_addr;
+ struct sockaddr_storage dst_addr;
+};
+
struct rdma_ucm_conn_param {
__u32 qp_num;
__u32 qkey;
^ permalink raw reply related
* [PATCH 12/26 v3] rdma/cm: Add support for AF_IB to cma_get_service_id
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
cma_get_service_id forms the service ID based on the port space
and port number of the rdma_cm_id. Extend the call to support
AF_IB, which contains the service ID directly. This will
be needed to support any arbitrary SID.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index cd4e197..4e205db 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1374,6 +1374,9 @@ err1:
static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr)
{
+ if (addr->sa_family == AF_IB)
+ return ((struct sockaddr_ib *) addr)->sib_sid;
+
return cpu_to_be64(((u64)ps << 16) + be16_to_cpu(cma_port(addr)));
}
^ permalink raw reply related
* [PATCH 14/26 v3] rdma/cm: Set qkey for AF_IB
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
Allow the user to specify the qkey when using AF_IB. The
qkey is added to struct rdma_ucm_conn_param in place of a reserved
field, but for backwards compatability, is only accessed if the
associated rdma_cm_id is using AF_IB.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 35 +++++++++++++++++++++--------------
drivers/infiniband/core/ucma.c | 8 +++++---
include/rdma/rdma_cm.h | 1 +
include/rdma/rdma_user_cm.h | 2 +-
4 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1264e97..13423bb 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -320,16 +320,25 @@ static inline unsigned short cma_family(struct rdma_id_private *id_priv)
return id_priv->id.route.addr.src_addr.ss_family;
}
-static int cma_set_qkey(struct rdma_id_private *id_priv)
+static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
{
struct ib_sa_mcmember_rec rec;
int ret = 0;
- if (id_priv->qkey)
+ if (id_priv->qkey) {
+ if (qkey && id_priv->qkey != qkey)
+ return -EINVAL;
return 0;
+ }
+
+ if (qkey) {
+ id_priv->qkey = qkey;
+ return 0;
+ }
switch (id_priv->id.ps) {
case RDMA_PS_UDP:
+ case RDMA_PS_IB:
id_priv->qkey = RDMA_UDP_QKEY;
break;
case RDMA_PS_IPOIB:
@@ -717,7 +726,7 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
if (id_priv->id.qp_type == IB_QPT_UD) {
- ret = cma_set_qkey(id_priv);
+ ret = cma_set_qkey(id_priv, 0);
if (ret)
return ret;
@@ -2687,15 +2696,10 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
event.status = ib_event->param.sidr_rep_rcvd.status;
break;
}
- ret = cma_set_qkey(id_priv);
+ ret = cma_set_qkey(id_priv, rep->qkey);
if (ret) {
event.event = RDMA_CM_EVENT_ADDR_ERROR;
- event.status = -EINVAL;
- break;
- }
- if (id_priv->qkey != rep->qkey) {
- event.event = RDMA_CM_EVENT_UNREACHABLE;
- event.status = -EINVAL;
+ event.status = ret;
break;
}
ib_init_ah_from_path(id_priv->id.device, id_priv->id.port_num,
@@ -2973,7 +2977,7 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
}
static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
- enum ib_cm_sidr_status status,
+ enum ib_cm_sidr_status status, u32 qkey,
const void *private_data, int private_data_len)
{
struct ib_cm_sidr_rep_param rep;
@@ -2982,7 +2986,7 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
memset(&rep, 0, sizeof rep);
rep.status = status;
if (status == IB_SIDR_SUCCESS) {
- ret = cma_set_qkey(id_priv);
+ ret = cma_set_qkey(id_priv, qkey);
if (ret)
return ret;
rep.qp_num = id_priv->qp_num;
@@ -3016,11 +3020,12 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
if (id->qp_type == IB_QPT_UD) {
if (conn_param)
ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
+ conn_param->qkey,
conn_param->private_data,
conn_param->private_data_len);
else
ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
- NULL, 0);
+ 0, NULL, 0);
} else {
if (conn_param)
ret = cma_accept_ib(id_priv, conn_param);
@@ -3081,7 +3086,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
switch (rdma_node_get_transport(id->device->node_type)) {
case RDMA_TRANSPORT_IB:
if (id->qp_type == IB_QPT_UD)
- ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
+ ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, 0,
private_data, private_data_len);
else
ret = ib_send_cm_rej(id_priv->cm_id.ib,
@@ -3142,6 +3147,8 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED))
return 0;
+ if (!status)
+ status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
mutex_lock(&id_priv->qp_mutex);
if (!status && id_priv->id.qp)
status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 8002ae6..52c606b 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -726,7 +726,8 @@ out:
return ret;
}
-static void ucma_copy_conn_param(struct rdma_conn_param *dst,
+static void ucma_copy_conn_param(struct rdma_cm_id *id,
+ struct rdma_conn_param *dst,
struct rdma_ucm_conn_param *src)
{
dst->private_data = src->private_data;
@@ -738,6 +739,7 @@ static void ucma_copy_conn_param(struct rdma_conn_param *dst,
dst->rnr_retry_count = src->rnr_retry_count;
dst->srq = src->srq;
dst->qp_num = src->qp_num;
+ dst->qkey = (id->route.addr.src_addr.ss_family == AF_IB) ? src->qkey : 0;
}
static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,
@@ -758,7 +760,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,
if (IS_ERR(ctx))
return PTR_ERR(ctx);
- ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+ ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param);
ret = rdma_connect(ctx->cm_id, &conn_param);
ucma_put_ctx(ctx);
return ret;
@@ -801,7 +803,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
return PTR_ERR(ctx);
if (cmd.conn_param.valid) {
- ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+ ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param);
mutex_lock(&file->mut);
ret = rdma_accept(ctx->cm_id, &conn_param);
if (!ret)
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 5eb3179..0bb190f 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -98,6 +98,7 @@ struct rdma_conn_param {
/* Fields below ignored if a QP is created on the rdma_cm_id. */
u8 srq;
u32 qp_num;
+ u32 qkey;
};
struct rdma_ud_param {
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index 5348a00..ca8d4d4 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -131,7 +131,7 @@ struct rdma_ucm_query_route_resp {
struct rdma_ucm_conn_param {
__u32 qp_num;
- __u32 reserved;
+ __u32 qkey;
__u8 private_data[RDMA_MAX_PRIVATE_DATA];
__u8 private_data_len;
__u8 srq;
^ permalink raw reply related
* [PATCH 19/26 v3] rdma/cm: Export cma_get_service_id
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Allow the rdma_ucm to query the IB service ID formed or
allocated by the rdma_cm by exporting the cma_get_service_id
functionality.
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 13 +++++++------
include/rdma/rdma_cm.h | 7 +++++++
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index d7bc654..8f9c05f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1377,13 +1377,14 @@ err1:
return ret;
}
-static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr)
+__be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr)
{
if (addr->sa_family == AF_IB)
return ((struct sockaddr_ib *) addr)->sib_sid;
- return cpu_to_be64(((u64)ps << 16) + be16_to_cpu(cma_port(addr)));
+ return cpu_to_be64(((u64)id->ps << 16) + be16_to_cpu(cma_port(addr)));
}
+EXPORT_SYMBOL(rdma_get_service_id);
static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
struct ib_cm_compare_data *compare)
@@ -1611,7 +1612,7 @@ static int cma_ib_listen(struct rdma_id_private *id_priv)
id_priv->cm_id.ib = id;
addr = cma_src_addr(id_priv);
- svc_id = cma_get_service_id(id_priv->id.ps, addr);
+ svc_id = rdma_get_service_id(&id_priv->id, addr);
if (cma_any_addr(addr))
ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL);
else {
@@ -1753,7 +1754,7 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
path_rec.numb_path = 1;
path_rec.reversible = 1;
- path_rec.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
+ path_rec.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
@@ -2767,7 +2768,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
id_priv->cm_id.ib = id;
req.path = id_priv->id.route.path_rec;
- req.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
+ req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8);
req.max_cm_retries = CMA_MAX_CM_RETRIES;
@@ -2821,7 +2822,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
if (route->num_paths == 2)
req.alternate_path = &route->path_rec[1];
- req.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
+ req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
req.qp_num = id_priv->qp_num;
req.qp_type = id_priv->id.qp_type;
req.starting_psn = id_priv->seq_num;
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 0bb190f..e240def 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -363,4 +363,11 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos);
*/
int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse);
+/**
+ * rdma_get_service_id - Return the IB service ID for a specified address.
+ * @id: Communication identifier associated with the address.
+ * @addr: Address for the service ID.
+ */
+__be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr);
+
#endif /* RDMA_CM_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/26 v3] rdma/cm: Do not modify sa_family when setting loopback address
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
cma_resolve_loopback is called after an rdma_cm_id has been
bound to a specific sa_family and port. Once the
source sa_family for the id has been set, do not modify it.
Only the actual IP address portion of the source address
needs to be set.
As part of this fix, we can simplify setting the source address
by moving the loopback address assignment from cma_resolve_loopback
to cma_bind_loopback. cma_bind_loopback is only invoked when
the source address is the loopback address.
Finally, add loopback support for AF_IB as part of the change.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 31 ++++++++++++++++++-------------
1 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index f09450e..4aee89a 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1942,6 +1942,23 @@ err:
}
EXPORT_SYMBOL(rdma_resolve_route);
+static void cma_set_loopback(struct sockaddr *addr)
+{
+ switch (addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ break;
+ case AF_INET6:
+ ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr,
+ 0, 0, 0, htonl(1));
+ break;
+ default:
+ ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr,
+ 0, 0, 0, htonl(1));
+ break;
+ }
+}
+
static int cma_bind_loopback(struct rdma_id_private *id_priv)
{
struct cma_device *cma_dev;
@@ -1982,6 +1999,7 @@ port_found:
ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
id_priv->id.port_num = p;
cma_attach_to_dev(id_priv, cma_dev);
+ cma_set_loopback((struct sockaddr *) &id_priv->id.route.addr.src_addr);
out:
mutex_unlock(&lock);
return ret;
@@ -2029,7 +2047,6 @@ out:
static int cma_resolve_loopback(struct rdma_id_private *id_priv)
{
struct cma_work *work;
- struct sockaddr *src, *dst;
union ib_gid gid;
int ret;
@@ -2046,18 +2063,6 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
- src = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
- if (cma_zero_addr(src)) {
- dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
- if ((src->sa_family = dst->sa_family) == AF_INET) {
- ((struct sockaddr_in *)src)->sin_addr =
- ((struct sockaddr_in *)dst)->sin_addr;
- } else {
- ((struct sockaddr_in6 *)src)->sin6_addr =
- ((struct sockaddr_in6 *)dst)->sin6_addr;
- }
- }
-
work->id = id_priv;
INIT_WORK(&work->work, cma_work_handler);
work->old_state = RDMA_CM_ADDR_QUERY;
^ permalink raw reply related
* [PATCH 11/26 v3] rdma/cm: Add support for AF_IB to rdma_resolve_route
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Allow rdma_resolve_route to handle the case where the user
specified the source and destination addresses using AF_IB.
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9d37c2f..cd4e197 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1733,6 +1733,7 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
struct ib_sa_path_rec path_rec;
ib_sa_comp_mask comp_mask;
struct sockaddr_in6 *sin6;
+ struct sockaddr_ib *sib;
memset(&path_rec, 0, sizeof path_rec);
rdma_addr_get_sgid(dev_addr, &path_rec.sgid);
@@ -1746,13 +1747,21 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID;
- if (cma_family(id_priv) == AF_INET) {
+ switch (cma_family(id_priv)) {
+ case AF_INET:
path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
- } else {
+ break;
+ case AF_INET6:
sin6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20);
comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
+ break;
+ case AF_IB:
+ sib = (struct sockaddr_ib *) cma_src_addr(id_priv);
+ path_rec.traffic_class = (u8) (be32_to_cpu(sib->sib_flowinfo) >> 20);
+ comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
+ break;
}
id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 8/26 v3] rdma/cm: Restrict AF_IB loopback to binding to IB devices only
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma@vger.kernel.org), netdev@vger.kernel.org
If a user specifies AF_IB as the source address for a loopback
connection, limit the resolution to IB devices only.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 0e661b4..b305963 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1971,26 +1971,38 @@ static void cma_set_loopback(struct sockaddr *addr)
static int cma_bind_loopback(struct rdma_id_private *id_priv)
{
- struct cma_device *cma_dev;
+ struct cma_device *cma_dev, *cur_dev;
struct ib_port_attr port_attr;
union ib_gid gid;
u16 pkey;
int ret;
u8 p;
+ cma_dev = NULL;
mutex_lock(&lock);
- if (list_empty(&dev_list)) {
+ list_for_each_entry(cur_dev, &dev_list, list) {
+ if (cma_family(id_priv) == AF_IB &&
+ rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB)
+ continue;
+
+ if (!cma_dev)
+ cma_dev = cur_dev;
+
+ for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
+ if (!ib_query_port(cur_dev->device, p, &port_attr) &&
+ port_attr.state == IB_PORT_ACTIVE) {
+ cma_dev = cur_dev;
+ goto port_found;
+ }
+ }
+ }
+
+ if (!cma_dev) {
ret = -ENODEV;
goto out;
}
- list_for_each_entry(cma_dev, &dev_list, list)
- for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p)
- if (!ib_query_port(cma_dev->device, p, &port_attr) &&
- port_attr.state == IB_PORT_ACTIVE)
- goto port_found;
p = 1;
- cma_dev = list_entry(dev_list.next, struct cma_device, list);
port_found:
ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
^ permalink raw reply related
* [PATCH 9/26 v3] rdma/cm: Verify that source and dest sa_family are the same
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index b305963..fa4ac4f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1839,14 +1839,9 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
struct rdma_addr *addr = &route->addr;
struct cma_work *work;
int ret;
- struct sockaddr_in *src_addr = (struct sockaddr_in *)&route->addr.src_addr;
- struct sockaddr_in *dst_addr = (struct sockaddr_in *)&route->addr.dst_addr;
struct net_device *ndev = NULL;
u16 vid;
- if (src_addr->sin_family != dst_addr->sin_family)
- return -EINVAL;
-
work = kzalloc(sizeof *work, GFP_KERNEL);
if (!work)
return -ENOMEM;
@@ -2122,6 +2117,9 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
return ret;
}
+ if (cma_family(id_priv) != dst_addr->sa_family)
+ return -EINVAL;
+
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY))
return -EINVAL;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 7/26 v3] rdma/cm: Add helper functions to return id address information
From: Hefty, Sean @ 2012-09-24 23:55 UTC (permalink / raw)
To: linux-rdma (linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org),
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Provide inline helpers to extract source and destination address
data from the rdma_cm_id.
Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
resending with netdev copied
drivers/infiniband/core/cma.c | 143 +++++++++++++++++++++--------------------
1 files changed, 72 insertions(+), 71 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 4aee89a..0e661b4 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -305,6 +305,21 @@ static void cma_release_dev(struct rdma_id_private *id_priv)
mutex_unlock(&lock);
}
+static inline struct sockaddr *cma_src_addr(struct rdma_id_private *id_priv)
+{
+ return (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+}
+
+static inline struct sockaddr *cma_dst_addr(struct rdma_id_private *id_priv)
+{
+ return (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
+}
+
+static inline unsigned short cma_family(struct rdma_id_private *id_priv)
+{
+ return id_priv->id.route.addr.src_addr.ss_family;
+}
+
static int cma_set_qkey(struct rdma_id_private *id_priv)
{
struct ib_sa_mcmember_rec rec;
@@ -895,8 +910,7 @@ static void cma_cancel_operation(struct rdma_id_private *id_priv,
cma_cancel_route(id_priv);
break;
case RDMA_CM_LISTEN:
- if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)
- && !id_priv->cma_dev)
+ if (cma_any_addr(cma_src_addr(id_priv)) && !id_priv->cma_dev)
cma_cancel_listens(id_priv);
break;
default:
@@ -1133,6 +1147,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
if (IS_ERR(id))
return NULL;
+ id_priv = container_of(id, struct rdma_id_private, id);
cma_save_net_info(&id->route.addr, &listen_id->route.addr,
ip_ver, port, src, dst);
@@ -1147,19 +1162,17 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
if (rt->num_paths == 2)
rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
- if (cma_any_addr((struct sockaddr *) &rt->addr.src_addr)) {
+ if (cma_any_addr(cma_src_addr(id_priv))) {
rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
} else {
- ret = cma_translate_addr((struct sockaddr *) &rt->addr.src_addr,
- &rt->addr.dev_addr);
+ ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
if (ret)
goto err;
}
rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
- id_priv = container_of(id, struct rdma_id_private, id);
id_priv->state = RDMA_CM_CONNECT;
return id_priv;
@@ -1183,7 +1196,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
if (IS_ERR(id))
return NULL;
-
+ id_priv = container_of(id, struct rdma_id_private, id);
if (cma_get_net_info(ib_event->private_data, listen_id->ps,
&ip_ver, &port, &src, &dst))
goto err;
@@ -1192,13 +1205,11 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
ip_ver, port, src, dst);
if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) {
- ret = cma_translate_addr((struct sockaddr *) &id->route.addr.src_addr,
- &id->route.addr.dev_addr);
+ ret = cma_translate_addr(cma_src_addr(id_priv), &id->route.addr.dev_addr);
if (ret)
goto err;
}
- id_priv = container_of(id, struct rdma_id_private, id);
id_priv->state = RDMA_CM_CONNECT;
return id_priv;
err:
@@ -1377,9 +1388,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
event.event = RDMA_CM_EVENT_DISCONNECTED;
break;
case IW_CM_EVENT_CONNECT_REPLY:
- sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+ sin = (struct sockaddr_in *) cma_src_addr(id_priv);
*sin = iw_event->local_addr;
- sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
+ sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
*sin = iw_event->remote_addr;
switch (iw_event->status) {
case 0:
@@ -1477,9 +1488,9 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
cm_id->context = conn_id;
cm_id->cm_handler = cma_iw_handler;
- sin = (struct sockaddr_in *) &new_cm_id->route.addr.src_addr;
+ sin = (struct sockaddr_in *) cma_src_addr(conn_id);
*sin = iw_event->local_addr;
- sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr;
+ sin = (struct sockaddr_in *) cma_dst_addr(conn_id);
*sin = iw_event->remote_addr;
ret = ib_query_device(conn_id->id.device, &attr);
@@ -1536,7 +1547,7 @@ static int cma_ib_listen(struct rdma_id_private *id_priv)
id_priv->cm_id.ib = id;
- addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+ addr = cma_src_addr(id_priv);
svc_id = cma_get_service_id(id_priv->id.ps, addr);
if (cma_any_addr(addr))
ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL);
@@ -1567,7 +1578,7 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)
id_priv->cm_id.iw = id;
- sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+ sin = (struct sockaddr_in *) cma_src_addr(id_priv);
id_priv->cm_id.iw->local_addr = *sin;
ret = iw_cm_listen(id_priv->cm_id.iw, backlog);
@@ -1605,8 +1616,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
dev_id_priv = container_of(id, struct rdma_id_private, id);
dev_id_priv->state = RDMA_CM_ADDR_BOUND;
- memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
- rdma_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
+ memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv),
+ rdma_addr_size(cma_src_addr(id_priv)));
cma_attach_to_dev(dev_id_priv, cma_dev);
list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
@@ -1663,29 +1674,28 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
struct cma_work *work)
{
- struct rdma_addr *addr = &id_priv->id.route.addr;
+ struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
struct ib_sa_path_rec path_rec;
ib_sa_comp_mask comp_mask;
struct sockaddr_in6 *sin6;
memset(&path_rec, 0, sizeof path_rec);
- rdma_addr_get_sgid(&addr->dev_addr, &path_rec.sgid);
- rdma_addr_get_dgid(&addr->dev_addr, &path_rec.dgid);
- path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr));
+ rdma_addr_get_sgid(dev_addr, &path_rec.sgid);
+ rdma_addr_get_dgid(dev_addr, &path_rec.dgid);
+ path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
path_rec.numb_path = 1;
path_rec.reversible = 1;
- path_rec.service_id = cma_get_service_id(id_priv->id.ps,
- (struct sockaddr *) &addr->dst_addr);
+ path_rec.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID;
- if (addr->src_addr.ss_family == AF_INET) {
+ if (cma_family(id_priv) == AF_INET) {
path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
} else {
- sin6 = (struct sockaddr_in6 *) &addr->src_addr;
+ sin6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20);
comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
}
@@ -1999,7 +2009,7 @@ port_found:
ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
id_priv->id.port_num = p;
cma_attach_to_dev(id_priv, cma_dev);
- cma_set_loopback((struct sockaddr *) &id_priv->id.route.addr.src_addr);
+ cma_set_loopback(cma_src_addr(id_priv));
out:
mutex_unlock(&lock);
return ret;
@@ -2027,8 +2037,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
event.event = RDMA_CM_EVENT_ADDR_ERROR;
event.status = status;
} else {
- memcpy(&id_priv->id.route.addr.src_addr, src_addr,
- rdma_addr_size(src_addr));
+ memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
}
@@ -2105,11 +2114,11 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
return -EINVAL;
atomic_inc(&id_priv->refcount);
- memcpy(&id->route.addr.dst_addr, dst_addr, rdma_addr_size(dst_addr));
+ memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
if (cma_any_addr(dst_addr))
ret = cma_resolve_loopback(id_priv);
else
- ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr,
+ ret = rdma_resolve_ip(&addr_client, cma_src_addr(id_priv),
dst_addr, &id->route.addr.dev_addr,
timeout_ms, addr_handler, id_priv);
if (ret)
@@ -2150,7 +2159,7 @@ static void cma_bind_port(struct rdma_bind_list *bind_list,
u64 sid, mask;
__be16 port;
- addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+ addr = cma_src_addr(id_priv);
port = htons(bind_list->port);
switch (addr->sa_family) {
@@ -2246,11 +2255,9 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
struct rdma_id_private *id_priv, uint8_t reuseaddr)
{
struct rdma_id_private *cur_id;
- struct sockaddr *addr, *cur_addr;
struct hlist_node *node;
- addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
- if (cma_any_addr(addr) && !reuseaddr)
+ if (cma_any_addr(cma_src_addr(id_priv)) && !reuseaddr)
return -EADDRNOTAVAIL;
hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
@@ -2259,11 +2266,10 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
if ((cur_id->state == RDMA_CM_LISTEN) ||
!reuseaddr || !cur_id->reuseaddr) {
- cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr;
- if (cma_any_addr(cur_addr))
+ if (cma_any_addr(cma_src_addr(cur_id)))
return -EADDRNOTAVAIL;
- if (!cma_addr_cmp(addr, cur_addr))
+ if (!cma_addr_cmp(cma_src_addr(id_priv), cma_src_addr(cur_id)))
return -EADDRINUSE;
}
}
@@ -2276,7 +2282,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
unsigned short snum;
int ret;
- snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr));
+ snum = ntohs(cma_port(cma_src_addr(id_priv)));
if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES;
@@ -2327,7 +2333,7 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
struct sockaddr_ib *sib;
u64 sid_ps, mask, sid;
- sib = (struct sockaddr_ib *) &id_priv->id.route.addr.src_addr;
+ sib = (struct sockaddr_ib *) cma_src_addr(id_priv);
mask = be64_to_cpu(sib->sib_sid_mask) & RDMA_IB_IP_PS_MASK;
sid = be64_to_cpu(sib->sib_sid) & mask;
@@ -2357,7 +2363,7 @@ static int cma_get_port(struct rdma_id_private *id_priv)
struct idr *ps;
int ret;
- if (id_priv->id.route.addr.src_addr.ss_family != AF_IB)
+ if (cma_family(id_priv) != AF_IB)
ps = cma_select_inet_ps(id_priv);
else
ps = cma_select_ib_ps(id_priv);
@@ -2365,7 +2371,7 @@ static int cma_get_port(struct rdma_id_private *id_priv)
return -EPROTONOSUPPORT;
mutex_lock(&lock);
- if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr))
+ if (cma_any_port(cma_src_addr(id_priv)))
ret = cma_alloc_any_port(ps, id_priv);
else
ret = cma_use_port(ps, id_priv);
@@ -2400,8 +2406,8 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
id_priv = container_of(id, struct rdma_id_private, id);
if (id_priv->state == RDMA_CM_IDLE) {
- ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET;
- ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr);
+ id->route.addr.src_addr.ss_family = AF_INET;
+ ret = rdma_bind_addr(id, cma_src_addr(id_priv));
if (ret)
return ret;
}
@@ -2470,7 +2476,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
goto err1;
}
- memcpy(&id->route.addr.src_addr, addr, rdma_addr_size(addr));
+ memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
ret = cma_get_port(id_priv);
if (ret)
goto err2;
@@ -2485,19 +2491,18 @@ err1:
}
EXPORT_SYMBOL(rdma_bind_addr);
-static int cma_format_hdr(void *hdr, enum rdma_port_space ps,
- struct rdma_route *route)
+static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv)
{
struct cma_hdr *cma_hdr;
struct sdp_hh *sdp_hdr;
- if (route->addr.src_addr.ss_family == AF_INET) {
+ if (cma_family(id_priv) == AF_INET) {
struct sockaddr_in *src4, *dst4;
- src4 = (struct sockaddr_in *) &route->addr.src_addr;
- dst4 = (struct sockaddr_in *) &route->addr.dst_addr;
+ src4 = (struct sockaddr_in *) cma_src_addr(id_priv);
+ dst4 = (struct sockaddr_in *) cma_dst_addr(id_priv);
- switch (ps) {
+ switch (id_priv->id.ps) {
case RDMA_PS_SDP:
sdp_hdr = hdr;
if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
@@ -2519,10 +2524,10 @@ static int cma_format_hdr(void *hdr, enum rdma_port_space ps,
} else {
struct sockaddr_in6 *src6, *dst6;
- src6 = (struct sockaddr_in6 *) &route->addr.src_addr;
- dst6 = (struct sockaddr_in6 *) &route->addr.dst_addr;
+ src6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
+ dst6 = (struct sockaddr_in6 *) cma_dst_addr(id_priv);
- switch (ps) {
+ switch (id_priv->id.ps) {
case RDMA_PS_SDP:
sdp_hdr = hdr;
if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
@@ -2613,7 +2618,6 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
struct rdma_conn_param *conn_param)
{
struct ib_cm_sidr_req_param req;
- struct rdma_route *route;
struct ib_cm_id *id;
int ret;
@@ -2630,8 +2634,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
memcpy((void *) req.private_data + sizeof(struct cma_hdr),
conn_param->private_data, conn_param->private_data_len);
- route = &id_priv->id.route;
- ret = cma_format_hdr((void *) req.private_data, id_priv->id.ps, route);
+ ret = cma_format_hdr((void *) req.private_data, id_priv);
if (ret)
goto out;
@@ -2643,9 +2646,8 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
}
id_priv->cm_id.ib = id;
- req.path = route->path_rec;
- req.service_id = cma_get_service_id(id_priv->id.ps,
- (struct sockaddr *) &route->addr.dst_addr);
+ req.path = id_priv->id.route.path_rec;
+ req.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8);
req.max_cm_retries = CMA_MAX_CM_RETRIES;
@@ -2690,7 +2692,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
id_priv->cm_id.ib = id;
route = &id_priv->id.route;
- ret = cma_format_hdr(private_data, id_priv->id.ps, route);
+ ret = cma_format_hdr(private_data, id_priv);
if (ret)
goto out;
req.private_data = private_data;
@@ -2699,8 +2701,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
if (route->num_paths == 2)
req.alternate_path = &route->path_rec[1];
- req.service_id = cma_get_service_id(id_priv->id.ps,
- (struct sockaddr *) &route->addr.dst_addr);
+ req.service_id = cma_get_service_id(id_priv->id.ps, cma_dst_addr(id_priv));
req.qp_num = id_priv->qp_num;
req.qp_type = id_priv->id.qp_type;
req.starting_psn = id_priv->seq_num;
@@ -2739,10 +2740,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
id_priv->cm_id.iw = cm_id;
- sin = (struct sockaddr_in*) &id_priv->id.route.addr.src_addr;
+ sin = (struct sockaddr_in *) cma_src_addr(id_priv);
cm_id->local_addr = *sin;
- sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
+ sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
cm_id->remote_addr = *sin;
ret = cma_modify_qp_rtr(id_priv, conn_param);
@@ -3507,29 +3508,29 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb)
id_stats->bound_dev_if =
id->route.addr.dev_addr.bound_dev_if;
- if (id->route.addr.src_addr.ss_family == AF_INET) {
+ if (cma_family(id_priv) == AF_INET) {
if (ibnl_put_attr(skb, nlh,
sizeof(struct sockaddr_in),
- &id->route.addr.src_addr,
+ cma_src_addr(id_priv),
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
goto out;
}
if (ibnl_put_attr(skb, nlh,
sizeof(struct sockaddr_in),
- &id->route.addr.dst_addr,
+ cma_dst_addr(id_priv),
RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
goto out;
}
- } else if (id->route.addr.src_addr.ss_family == AF_INET6) {
+ } else if (cma_family(id_priv) == AF_INET6) {
if (ibnl_put_attr(skb, nlh,
sizeof(struct sockaddr_in6),
- &id->route.addr.src_addr,
+ cma_src_addr(id_priv),
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
goto out;
}
if (ibnl_put_attr(skb, nlh,
sizeof(struct sockaddr_in6),
- &id->route.addr.dst_addr,
+ cma_dst_addr(id_priv),
RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
goto out;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox