@@ -56,6 +56,11 @@ MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("Generic RDMA CM Agent");
MODULE_LICENSE("Dual BSD/GPL");
+int unify_tcp_port_space = 1;
+module_param(unify_tcp_port_space, int, 0644);
+MODULE_PARM_DESC(unify_tcp_port_space, "Unify the host TCP and RDMA port "
+ "space allocation (default=1)");
+
#define CMA_CM_RESPONSE_TIMEOUT 20
#define CMA_MAX_CM_RETRIES 15
#define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24)
@@ -118,6 +123,7 @@ struct rdma_id_private {
struct rdma_cm_id id;
struct rdma_bind_list *bind_list;
+ struct socket *sock;
struct hlist_node node;
struct list_head list; /* listen_any_list or cma_device.list */
struct list_head listen_list; /* per device listens */
@@ -806,6 +812,8 @@ static void cma_release_port(struct rdma_id_private *id_priv)
kfree(bind_list);
}
mutex_unlock(&lock);
+ if (id_priv->sock)
+ sock_release(id_priv->sock);
}
static void cma_leave_mc_groups(struct rdma_id_private *id_priv)
@@ -2035,6 +2043,37 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
return 0;
}
+static int cma_get_tcp_port(struct rdma_id_private *id_priv)
+{
+ int ret;
+ int size;
+ struct socket *sock;
+
+ ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (ret)
+ return ret;
+
+ size = ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr);
+
+ ret = sock->ops->bind(sock,
+ (struct sockaddr *) &id_priv->id.route.addr.src_addr,
+ size);
+ if (ret)
+ goto err;
+
+ ret = sock->ops->getname(sock,
+ (struct sockaddr *) &id_priv->id.route.addr.src_addr,
+ &size, 0);
+ if (ret)
+ goto err;
+
+ id_priv->sock = sock;
+ return 0;
+err:
+ sock_release(sock);
+ return ret;
+}
+
static int cma_get_port(struct rdma_id_private *id_priv)
{
struct idr *ps;
@@ -2046,6 +2085,11 @@ static int cma_get_port(struct rdma_id_private *id_priv)
break;
case RDMA_PS_TCP:
ps = &tcp_ps;
+ if (unify_tcp_port_space) {
+ ret = cma_get_tcp_port(id_priv);
+ if (ret)
+ goto out;
+ }
break;
case RDMA_PS_UDP:
ps = &udp_ps;
@@ -2063,7 +2107,7 @@ static int cma_get_port(struct rdma_id_private *id_priv)
else
ret = cma_use_port(ps, id_priv);
mutex_unlock(&lock);
-
+out:
return ret;
}