提交 4be74b42 编写于 作者: H Haggai Eran 提交者: Doug Ledford

IB/cma: Separate port allocation to network namespaces

Keep a struct for each network namespace containing the IDRs for the RDMA
CM port spaces. The struct is created dynamically using the generic_net
mechanism.

This patch is internal infrastructure work for the following patches. In
this patch, init_net is statically used as the network namespace for
the new port-space API.
Signed-off-by: NHaggai Eran <haggaie@mellanox.com>
Signed-off-by: NYotam Kenneth <yotamke@mellanox.com>
Signed-off-by: NShachar Raindel <raindel@mellanox.com>
Signed-off-by: NGuy Shapiro <guysh@mellanox.com>
Signed-off-by: NDoug Ledford <dledford@redhat.com>
上级 565edd1d
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <net/route.h> #include <net/route.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/ip_fib.h> #include <net/ip_fib.h>
...@@ -110,22 +112,33 @@ static LIST_HEAD(dev_list); ...@@ -110,22 +112,33 @@ static LIST_HEAD(dev_list);
static LIST_HEAD(listen_any_list); static LIST_HEAD(listen_any_list);
static DEFINE_MUTEX(lock); static DEFINE_MUTEX(lock);
static struct workqueue_struct *cma_wq; static struct workqueue_struct *cma_wq;
static DEFINE_IDR(tcp_ps); static int cma_pernet_id;
static DEFINE_IDR(udp_ps);
static DEFINE_IDR(ipoib_ps);
static DEFINE_IDR(ib_ps);
static struct idr *cma_idr(enum rdma_port_space ps) struct cma_pernet {
struct idr tcp_ps;
struct idr udp_ps;
struct idr ipoib_ps;
struct idr ib_ps;
};
static struct cma_pernet *cma_pernet(struct net *net)
{
return net_generic(net, cma_pernet_id);
}
static struct idr *cma_pernet_idr(struct net *net, enum rdma_port_space ps)
{ {
struct cma_pernet *pernet = cma_pernet(net);
switch (ps) { switch (ps) {
case RDMA_PS_TCP: case RDMA_PS_TCP:
return &tcp_ps; return &pernet->tcp_ps;
case RDMA_PS_UDP: case RDMA_PS_UDP:
return &udp_ps; return &pernet->udp_ps;
case RDMA_PS_IPOIB: case RDMA_PS_IPOIB:
return &ipoib_ps; return &pernet->ipoib_ps;
case RDMA_PS_IB: case RDMA_PS_IB:
return &ib_ps; return &pernet->ib_ps;
default: default:
return NULL; return NULL;
} }
...@@ -145,24 +158,25 @@ struct rdma_bind_list { ...@@ -145,24 +158,25 @@ struct rdma_bind_list {
unsigned short port; unsigned short port;
}; };
static int cma_ps_alloc(enum rdma_port_space ps, static int cma_ps_alloc(struct net *net, enum rdma_port_space ps,
struct rdma_bind_list *bind_list, int snum) struct rdma_bind_list *bind_list, int snum)
{ {
struct idr *idr = cma_idr(ps); struct idr *idr = cma_pernet_idr(net, ps);
return idr_alloc(idr, bind_list, snum, snum + 1, GFP_KERNEL); return idr_alloc(idr, bind_list, snum, snum + 1, GFP_KERNEL);
} }
static struct rdma_bind_list *cma_ps_find(enum rdma_port_space ps, int snum) static struct rdma_bind_list *cma_ps_find(struct net *net,
enum rdma_port_space ps, int snum)
{ {
struct idr *idr = cma_idr(ps); struct idr *idr = cma_pernet_idr(net, ps);
return idr_find(idr, snum); return idr_find(idr, snum);
} }
static void cma_ps_remove(enum rdma_port_space ps, int snum) static void cma_ps_remove(struct net *net, enum rdma_port_space ps, int snum)
{ {
struct idr *idr = cma_idr(ps); struct idr *idr = cma_pernet_idr(net, ps);
idr_remove(idr, snum); idr_remove(idr, snum);
} }
...@@ -1325,7 +1339,8 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id, ...@@ -1325,7 +1339,8 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
} }
} }
bind_list = cma_ps_find(rdma_ps_from_service_id(req.service_id), bind_list = cma_ps_find(&init_net,
rdma_ps_from_service_id(req.service_id),
cma_port_from_service_id(req.service_id)); cma_port_from_service_id(req.service_id));
id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev); id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
if (IS_ERR(id_priv) && *net_dev) { if (IS_ERR(id_priv) && *net_dev) {
...@@ -1403,7 +1418,7 @@ static void cma_release_port(struct rdma_id_private *id_priv) ...@@ -1403,7 +1418,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
mutex_lock(&lock); mutex_lock(&lock);
hlist_del(&id_priv->node); hlist_del(&id_priv->node);
if (hlist_empty(&bind_list->owners)) { if (hlist_empty(&bind_list->owners)) {
cma_ps_remove(bind_list->ps, bind_list->port); cma_ps_remove(&init_net, bind_list->ps, bind_list->port);
kfree(bind_list); kfree(bind_list);
} }
mutex_unlock(&lock); mutex_unlock(&lock);
...@@ -2693,7 +2708,7 @@ static int cma_alloc_port(enum rdma_port_space ps, ...@@ -2693,7 +2708,7 @@ static int cma_alloc_port(enum rdma_port_space ps,
if (!bind_list) if (!bind_list)
return -ENOMEM; return -ENOMEM;
ret = cma_ps_alloc(ps, bind_list, snum); ret = cma_ps_alloc(&init_net, ps, bind_list, snum);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -2718,7 +2733,7 @@ static int cma_alloc_any_port(enum rdma_port_space ps, ...@@ -2718,7 +2733,7 @@ static int cma_alloc_any_port(enum rdma_port_space ps,
rover = prandom_u32() % remaining + low; rover = prandom_u32() % remaining + low;
retry: retry:
if (last_used_port != rover && if (last_used_port != rover &&
!cma_ps_find(ps, (unsigned short)rover)) { !cma_ps_find(&init_net, ps, (unsigned short)rover)) {
int ret = cma_alloc_port(ps, id_priv, rover); int ret = cma_alloc_port(ps, id_priv, rover);
/* /*
* Remember previously used port number in order to avoid * Remember previously used port number in order to avoid
...@@ -2784,7 +2799,7 @@ static int cma_use_port(enum rdma_port_space ps, ...@@ -2784,7 +2799,7 @@ static int cma_use_port(enum rdma_port_space ps,
if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
bind_list = cma_ps_find(ps, snum); bind_list = cma_ps_find(&init_net, ps, snum);
if (!bind_list) { if (!bind_list) {
ret = cma_alloc_port(ps, id_priv, snum); ret = cma_alloc_port(ps, id_priv, snum);
} else { } else {
...@@ -4004,6 +4019,35 @@ static const struct ibnl_client_cbs cma_cb_table[] = { ...@@ -4004,6 +4019,35 @@ static const struct ibnl_client_cbs cma_cb_table[] = {
.module = THIS_MODULE }, .module = THIS_MODULE },
}; };
static int cma_init_net(struct net *net)
{
struct cma_pernet *pernet = cma_pernet(net);
idr_init(&pernet->tcp_ps);
idr_init(&pernet->udp_ps);
idr_init(&pernet->ipoib_ps);
idr_init(&pernet->ib_ps);
return 0;
}
static void cma_exit_net(struct net *net)
{
struct cma_pernet *pernet = cma_pernet(net);
idr_destroy(&pernet->tcp_ps);
idr_destroy(&pernet->udp_ps);
idr_destroy(&pernet->ipoib_ps);
idr_destroy(&pernet->ib_ps);
}
static struct pernet_operations cma_pernet_operations = {
.init = cma_init_net,
.exit = cma_exit_net,
.id = &cma_pernet_id,
.size = sizeof(struct cma_pernet),
};
static int __init cma_init(void) static int __init cma_init(void)
{ {
int ret; int ret;
...@@ -4012,6 +4056,10 @@ static int __init cma_init(void) ...@@ -4012,6 +4056,10 @@ static int __init cma_init(void)
if (!cma_wq) if (!cma_wq)
return -ENOMEM; return -ENOMEM;
ret = register_pernet_subsys(&cma_pernet_operations);
if (ret)
goto err_wq;
ib_sa_register_client(&sa_client); ib_sa_register_client(&sa_client);
rdma_addr_register_client(&addr_client); rdma_addr_register_client(&addr_client);
register_netdevice_notifier(&cma_nb); register_netdevice_notifier(&cma_nb);
...@@ -4029,6 +4077,7 @@ static int __init cma_init(void) ...@@ -4029,6 +4077,7 @@ static int __init cma_init(void)
unregister_netdevice_notifier(&cma_nb); unregister_netdevice_notifier(&cma_nb);
rdma_addr_unregister_client(&addr_client); rdma_addr_unregister_client(&addr_client);
ib_sa_unregister_client(&sa_client); ib_sa_unregister_client(&sa_client);
err_wq:
destroy_workqueue(cma_wq); destroy_workqueue(cma_wq);
return ret; return ret;
} }
...@@ -4040,11 +4089,8 @@ static void __exit cma_cleanup(void) ...@@ -4040,11 +4089,8 @@ static void __exit cma_cleanup(void)
unregister_netdevice_notifier(&cma_nb); unregister_netdevice_notifier(&cma_nb);
rdma_addr_unregister_client(&addr_client); rdma_addr_unregister_client(&addr_client);
ib_sa_unregister_client(&sa_client); ib_sa_unregister_client(&sa_client);
unregister_pernet_subsys(&cma_pernet_operations);
destroy_workqueue(cma_wq); destroy_workqueue(cma_wq);
idr_destroy(&tcp_ps);
idr_destroy(&udp_ps);
idr_destroy(&ipoib_ps);
idr_destroy(&ib_ps);
} }
module_init(cma_init); module_init(cma_init);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部