Commit 9eccfe10 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier

RDMA/cxgb4: Add support for iWARP Port Mapper user space service

Based on original work by Vipul Pandya.
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>

[ Fix htons -> ntohs to make sparse happy.  - Roland ]
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 5647263c
This diff is collapsed.
...@@ -77,6 +77,16 @@ struct c4iw_debugfs_data { ...@@ -77,6 +77,16 @@ struct c4iw_debugfs_data {
int pos; int pos;
}; };
/* registered cxgb4 netlink callbacks */
static struct ibnl_client_cbs c4iw_nl_cb_table[] = {
[RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb},
[RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb},
[RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb},
[RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb},
[RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb},
[RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb}
};
static int count_idrs(int id, void *p, void *data) static int count_idrs(int id, void *p, void *data)
{ {
int *countp = data; int *countp = data;
...@@ -113,35 +123,49 @@ static int dump_qp(int id, void *p, void *data) ...@@ -113,35 +123,49 @@ static int dump_qp(int id, void *p, void *data)
&qp->ep->com.local_addr; &qp->ep->com.local_addr;
struct sockaddr_in *rsin = (struct sockaddr_in *) struct sockaddr_in *rsin = (struct sockaddr_in *)
&qp->ep->com.remote_addr; &qp->ep->com.remote_addr;
struct sockaddr_in *mapped_lsin = (struct sockaddr_in *)
&qp->ep->com.mapped_local_addr;
struct sockaddr_in *mapped_rsin = (struct sockaddr_in *)
&qp->ep->com.mapped_remote_addr;
cc = snprintf(qpd->buf + qpd->pos, space, cc = snprintf(qpd->buf + qpd->pos, space,
"rc qp sq id %u rq id %u state %u " "rc qp sq id %u rq id %u state %u "
"onchip %u ep tid %u state %u " "onchip %u ep tid %u state %u "
"%pI4:%u->%pI4:%u\n", "%pI4:%u/%u->%pI4:%u/%u\n",
qp->wq.sq.qid, qp->wq.rq.qid, qp->wq.sq.qid, qp->wq.rq.qid,
(int)qp->attr.state, (int)qp->attr.state,
qp->wq.sq.flags & T4_SQ_ONCHIP, qp->wq.sq.flags & T4_SQ_ONCHIP,
qp->ep->hwtid, (int)qp->ep->com.state, qp->ep->hwtid, (int)qp->ep->com.state,
&lsin->sin_addr, ntohs(lsin->sin_port), &lsin->sin_addr, ntohs(lsin->sin_port),
&rsin->sin_addr, ntohs(rsin->sin_port)); ntohs(mapped_lsin->sin_port),
&rsin->sin_addr, ntohs(rsin->sin_port),
ntohs(mapped_rsin->sin_port));
} else { } else {
struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)
&qp->ep->com.local_addr; &qp->ep->com.local_addr;
struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *)
&qp->ep->com.remote_addr; &qp->ep->com.remote_addr;
struct sockaddr_in6 *mapped_lsin6 =
(struct sockaddr_in6 *)
&qp->ep->com.mapped_local_addr;
struct sockaddr_in6 *mapped_rsin6 =
(struct sockaddr_in6 *)
&qp->ep->com.mapped_remote_addr;
cc = snprintf(qpd->buf + qpd->pos, space, cc = snprintf(qpd->buf + qpd->pos, space,
"rc qp sq id %u rq id %u state %u " "rc qp sq id %u rq id %u state %u "
"onchip %u ep tid %u state %u " "onchip %u ep tid %u state %u "
"%pI6:%u->%pI6:%u\n", "%pI6:%u/%u->%pI6:%u/%u\n",
qp->wq.sq.qid, qp->wq.rq.qid, qp->wq.sq.qid, qp->wq.rq.qid,
(int)qp->attr.state, (int)qp->attr.state,
qp->wq.sq.flags & T4_SQ_ONCHIP, qp->wq.sq.flags & T4_SQ_ONCHIP,
qp->ep->hwtid, (int)qp->ep->com.state, qp->ep->hwtid, (int)qp->ep->com.state,
&lsin6->sin6_addr, &lsin6->sin6_addr,
ntohs(lsin6->sin6_port), ntohs(lsin6->sin6_port),
ntohs(mapped_lsin6->sin6_port),
&rsin6->sin6_addr, &rsin6->sin6_addr,
ntohs(rsin6->sin6_port)); ntohs(rsin6->sin6_port),
ntohs(mapped_rsin6->sin6_port));
} }
} else } else
cc = snprintf(qpd->buf + qpd->pos, space, cc = snprintf(qpd->buf + qpd->pos, space,
...@@ -386,31 +410,43 @@ static int dump_ep(int id, void *p, void *data) ...@@ -386,31 +410,43 @@ static int dump_ep(int id, void *p, void *data)
&ep->com.local_addr; &ep->com.local_addr;
struct sockaddr_in *rsin = (struct sockaddr_in *) struct sockaddr_in *rsin = (struct sockaddr_in *)
&ep->com.remote_addr; &ep->com.remote_addr;
struct sockaddr_in *mapped_lsin = (struct sockaddr_in *)
&ep->com.mapped_local_addr;
struct sockaddr_in *mapped_rsin = (struct sockaddr_in *)
&ep->com.mapped_remote_addr;
cc = snprintf(epd->buf + epd->pos, space, cc = snprintf(epd->buf + epd->pos, space,
"ep %p cm_id %p qp %p state %d flags 0x%lx " "ep %p cm_id %p qp %p state %d flags 0x%lx "
"history 0x%lx hwtid %d atid %d " "history 0x%lx hwtid %d atid %d "
"%pI4:%d <-> %pI4:%d\n", "%pI4:%d/%d <-> %pI4:%d/%d\n",
ep, ep->com.cm_id, ep->com.qp, ep, ep->com.cm_id, ep->com.qp,
(int)ep->com.state, ep->com.flags, (int)ep->com.state, ep->com.flags,
ep->com.history, ep->hwtid, ep->atid, ep->com.history, ep->hwtid, ep->atid,
&lsin->sin_addr, ntohs(lsin->sin_port), &lsin->sin_addr, ntohs(lsin->sin_port),
&rsin->sin_addr, ntohs(rsin->sin_port)); ntohs(mapped_lsin->sin_port),
&rsin->sin_addr, ntohs(rsin->sin_port),
ntohs(mapped_rsin->sin_port));
} else { } else {
struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)
&ep->com.local_addr; &ep->com.local_addr;
struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *)
&ep->com.remote_addr; &ep->com.remote_addr;
struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *)
&ep->com.mapped_local_addr;
struct sockaddr_in6 *mapped_rsin6 = (struct sockaddr_in6 *)
&ep->com.mapped_remote_addr;
cc = snprintf(epd->buf + epd->pos, space, cc = snprintf(epd->buf + epd->pos, space,
"ep %p cm_id %p qp %p state %d flags 0x%lx " "ep %p cm_id %p qp %p state %d flags 0x%lx "
"history 0x%lx hwtid %d atid %d " "history 0x%lx hwtid %d atid %d "
"%pI6:%d <-> %pI6:%d\n", "%pI6:%d/%d <-> %pI6:%d/%d\n",
ep, ep->com.cm_id, ep->com.qp, ep, ep->com.cm_id, ep->com.qp,
(int)ep->com.state, ep->com.flags, (int)ep->com.state, ep->com.flags,
ep->com.history, ep->hwtid, ep->atid, ep->com.history, ep->hwtid, ep->atid,
&lsin6->sin6_addr, ntohs(lsin6->sin6_port), &lsin6->sin6_addr, ntohs(lsin6->sin6_port),
&rsin6->sin6_addr, ntohs(rsin6->sin6_port)); ntohs(mapped_lsin6->sin6_port),
&rsin6->sin6_addr, ntohs(rsin6->sin6_port),
ntohs(mapped_rsin6->sin6_port));
} }
if (cc < space) if (cc < space)
epd->pos += cc; epd->pos += cc;
...@@ -431,23 +467,29 @@ static int dump_listen_ep(int id, void *p, void *data) ...@@ -431,23 +467,29 @@ static int dump_listen_ep(int id, void *p, void *data)
if (ep->com.local_addr.ss_family == AF_INET) { if (ep->com.local_addr.ss_family == AF_INET) {
struct sockaddr_in *lsin = (struct sockaddr_in *) struct sockaddr_in *lsin = (struct sockaddr_in *)
&ep->com.local_addr; &ep->com.local_addr;
struct sockaddr_in *mapped_lsin = (struct sockaddr_in *)
&ep->com.mapped_local_addr;
cc = snprintf(epd->buf + epd->pos, space, cc = snprintf(epd->buf + epd->pos, space,
"ep %p cm_id %p state %d flags 0x%lx stid %d " "ep %p cm_id %p state %d flags 0x%lx stid %d "
"backlog %d %pI4:%d\n", "backlog %d %pI4:%d/%d\n",
ep, ep->com.cm_id, (int)ep->com.state, ep, ep->com.cm_id, (int)ep->com.state,
ep->com.flags, ep->stid, ep->backlog, ep->com.flags, ep->stid, ep->backlog,
&lsin->sin_addr, ntohs(lsin->sin_port)); &lsin->sin_addr, ntohs(lsin->sin_port),
ntohs(mapped_lsin->sin_port));
} else { } else {
struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)
&ep->com.local_addr; &ep->com.local_addr;
struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *)
&ep->com.mapped_local_addr;
cc = snprintf(epd->buf + epd->pos, space, cc = snprintf(epd->buf + epd->pos, space,
"ep %p cm_id %p state %d flags 0x%lx stid %d " "ep %p cm_id %p state %d flags 0x%lx stid %d "
"backlog %d %pI6:%d\n", "backlog %d %pI6:%d/%d\n",
ep, ep->com.cm_id, (int)ep->com.state, ep, ep->com.cm_id, (int)ep->com.state,
ep->com.flags, ep->stid, ep->backlog, ep->com.flags, ep->stid, ep->backlog,
&lsin6->sin6_addr, ntohs(lsin6->sin6_port)); &lsin6->sin6_addr, ntohs(lsin6->sin6_port),
ntohs(mapped_lsin6->sin6_port));
} }
if (cc < space) if (cc < space)
epd->pos += cc; epd->pos += cc;
...@@ -687,6 +729,7 @@ static void c4iw_dealloc(struct uld_ctx *ctx) ...@@ -687,6 +729,7 @@ static void c4iw_dealloc(struct uld_ctx *ctx)
if (ctx->dev->rdev.oc_mw_kva) if (ctx->dev->rdev.oc_mw_kva)
iounmap(ctx->dev->rdev.oc_mw_kva); iounmap(ctx->dev->rdev.oc_mw_kva);
ib_dealloc_device(&ctx->dev->ibdev); ib_dealloc_device(&ctx->dev->ibdev);
iwpm_exit(RDMA_NL_C4IW);
ctx->dev = NULL; ctx->dev = NULL;
} }
...@@ -780,6 +823,14 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) ...@@ -780,6 +823,14 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
c4iw_debugfs_root); c4iw_debugfs_root);
setup_debugfs(devp); setup_debugfs(devp);
} }
ret = iwpm_init(RDMA_NL_C4IW);
if (ret) {
pr_err("port mapper initialization failed with %d\n", ret);
ib_dealloc_device(&devp->ibdev);
return ERR_PTR(ret);
}
return devp; return devp;
} }
...@@ -1274,6 +1325,11 @@ static int __init c4iw_init_module(void) ...@@ -1274,6 +1325,11 @@ static int __init c4iw_init_module(void)
printk(KERN_WARNING MOD printk(KERN_WARNING MOD
"could not create debugfs entry, continuing\n"); "could not create debugfs entry, continuing\n");
if (ibnl_add_client(RDMA_NL_C4IW, RDMA_NL_IWPM_NUM_OPS,
c4iw_nl_cb_table))
pr_err("%s[%u]: Failed to add netlink callback\n"
, __func__, __LINE__);
cxgb4_register_uld(CXGB4_ULD_RDMA, &c4iw_uld_info); cxgb4_register_uld(CXGB4_ULD_RDMA, &c4iw_uld_info);
return 0; return 0;
...@@ -1291,6 +1347,7 @@ static void __exit c4iw_exit_module(void) ...@@ -1291,6 +1347,7 @@ static void __exit c4iw_exit_module(void)
} }
mutex_unlock(&dev_mutex); mutex_unlock(&dev_mutex);
cxgb4_unregister_uld(CXGB4_ULD_RDMA); cxgb4_unregister_uld(CXGB4_ULD_RDMA);
ibnl_remove_client(RDMA_NL_C4IW);
c4iw_cm_term(); c4iw_cm_term();
debugfs_remove_recursive(c4iw_debugfs_root); debugfs_remove_recursive(c4iw_debugfs_root);
} }
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
#include <rdma/ib_verbs.h> #include <rdma/ib_verbs.h>
#include <rdma/iw_cm.h> #include <rdma/iw_cm.h>
#include <rdma/rdma_netlink.h>
#include <rdma/iw_portmap.h>
#include "cxgb4.h" #include "cxgb4.h"
#include "cxgb4_uld.h" #include "cxgb4_uld.h"
...@@ -728,6 +730,7 @@ enum c4iw_ep_flags { ...@@ -728,6 +730,7 @@ enum c4iw_ep_flags {
CLOSE_SENT = 3, CLOSE_SENT = 3,
TIMEOUT = 4, TIMEOUT = 4,
QP_REFERENCED = 5, QP_REFERENCED = 5,
RELEASE_MAPINFO = 6,
}; };
enum c4iw_ep_history { enum c4iw_ep_history {
...@@ -764,6 +767,8 @@ struct c4iw_ep_common { ...@@ -764,6 +767,8 @@ struct c4iw_ep_common {
struct mutex mutex; struct mutex mutex;
struct sockaddr_storage local_addr; struct sockaddr_storage local_addr;
struct sockaddr_storage remote_addr; struct sockaddr_storage remote_addr;
struct sockaddr_storage mapped_local_addr;
struct sockaddr_storage mapped_remote_addr;
struct c4iw_wr_wait wr_wait; struct c4iw_wr_wait wr_wait;
unsigned long flags; unsigned long flags;
unsigned long history; unsigned long history;
...@@ -807,6 +812,45 @@ struct c4iw_ep { ...@@ -807,6 +812,45 @@ struct c4iw_ep {
unsigned int retry_count; unsigned int retry_count;
}; };
static inline void print_addr(struct c4iw_ep_common *epc, const char *func,
const char *msg)
{
#define SINA(a) (&(((struct sockaddr_in *)(a))->sin_addr.s_addr))
#define SINP(a) ntohs(((struct sockaddr_in *)(a))->sin_port)
#define SIN6A(a) (&(((struct sockaddr_in6 *)(a))->sin6_addr))
#define SIN6P(a) ntohs(((struct sockaddr_in6 *)(a))->sin6_port)
if (c4iw_debug) {
switch (epc->local_addr.ss_family) {
case AF_INET:
PDBG("%s %s %pI4:%u/%u <-> %pI4:%u/%u\n",
func, msg, SINA(&epc->local_addr),
SINP(&epc->local_addr),
SINP(&epc->mapped_local_addr),
SINA(&epc->remote_addr),
SINP(&epc->remote_addr),
SINP(&epc->mapped_remote_addr));
break;
case AF_INET6:
PDBG("%s %s %pI6:%u/%u <-> %pI6:%u/%u\n",
func, msg, SIN6A(&epc->local_addr),
SIN6P(&epc->local_addr),
SIN6P(&epc->mapped_local_addr),
SIN6A(&epc->remote_addr),
SIN6P(&epc->remote_addr),
SIN6P(&epc->mapped_remote_addr));
break;
default:
break;
}
}
#undef SINA
#undef SINP
#undef SIN6A
#undef SIN6P
}
static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id)
{ {
return cm_id->provider_data; return cm_id->provider_data;
......
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