Skip to content

Commit 4be74b4

Browse files
haggaiedledford
authored andcommitted
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: Haggai Eran <[email protected]> Signed-off-by: Yotam Kenneth <[email protected]> Signed-off-by: Shachar Raindel <[email protected]> Signed-off-by: Guy Shapiro <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 565edd1 commit 4be74b4

File tree

1 file changed

+70
-24
lines changed
  • drivers/infiniband/core

1 file changed

+70
-24
lines changed

drivers/infiniband/core/cma.c

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include <linux/module.h>
4545
#include <net/route.h>
4646

47+
#include <net/net_namespace.h>
48+
#include <net/netns/generic.h>
4749
#include <net/tcp.h>
4850
#include <net/ipv6.h>
4951
#include <net/ip_fib.h>
@@ -110,22 +112,33 @@ static LIST_HEAD(dev_list);
110112
static LIST_HEAD(listen_any_list);
111113
static DEFINE_MUTEX(lock);
112114
static struct workqueue_struct *cma_wq;
113-
static DEFINE_IDR(tcp_ps);
114-
static DEFINE_IDR(udp_ps);
115-
static DEFINE_IDR(ipoib_ps);
116-
static DEFINE_IDR(ib_ps);
115+
static int cma_pernet_id;
117116

118-
static struct idr *cma_idr(enum rdma_port_space ps)
117+
struct cma_pernet {
118+
struct idr tcp_ps;
119+
struct idr udp_ps;
120+
struct idr ipoib_ps;
121+
struct idr ib_ps;
122+
};
123+
124+
static struct cma_pernet *cma_pernet(struct net *net)
125+
{
126+
return net_generic(net, cma_pernet_id);
127+
}
128+
129+
static struct idr *cma_pernet_idr(struct net *net, enum rdma_port_space ps)
119130
{
131+
struct cma_pernet *pernet = cma_pernet(net);
132+
120133
switch (ps) {
121134
case RDMA_PS_TCP:
122-
return &tcp_ps;
135+
return &pernet->tcp_ps;
123136
case RDMA_PS_UDP:
124-
return &udp_ps;
137+
return &pernet->udp_ps;
125138
case RDMA_PS_IPOIB:
126-
return &ipoib_ps;
139+
return &pernet->ipoib_ps;
127140
case RDMA_PS_IB:
128-
return &ib_ps;
141+
return &pernet->ib_ps;
129142
default:
130143
return NULL;
131144
}
@@ -145,24 +158,25 @@ struct rdma_bind_list {
145158
unsigned short port;
146159
};
147160

148-
static int cma_ps_alloc(enum rdma_port_space ps,
161+
static int cma_ps_alloc(struct net *net, enum rdma_port_space ps,
149162
struct rdma_bind_list *bind_list, int snum)
150163
{
151-
struct idr *idr = cma_idr(ps);
164+
struct idr *idr = cma_pernet_idr(net, ps);
152165

153166
return idr_alloc(idr, bind_list, snum, snum + 1, GFP_KERNEL);
154167
}
155168

156-
static struct rdma_bind_list *cma_ps_find(enum rdma_port_space ps, int snum)
169+
static struct rdma_bind_list *cma_ps_find(struct net *net,
170+
enum rdma_port_space ps, int snum)
157171
{
158-
struct idr *idr = cma_idr(ps);
172+
struct idr *idr = cma_pernet_idr(net, ps);
159173

160174
return idr_find(idr, snum);
161175
}
162176

163-
static void cma_ps_remove(enum rdma_port_space ps, int snum)
177+
static void cma_ps_remove(struct net *net, enum rdma_port_space ps, int snum)
164178
{
165-
struct idr *idr = cma_idr(ps);
179+
struct idr *idr = cma_pernet_idr(net, ps);
166180

167181
idr_remove(idr, snum);
168182
}
@@ -1325,7 +1339,8 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
13251339
}
13261340
}
13271341

1328-
bind_list = cma_ps_find(rdma_ps_from_service_id(req.service_id),
1342+
bind_list = cma_ps_find(&init_net,
1343+
rdma_ps_from_service_id(req.service_id),
13291344
cma_port_from_service_id(req.service_id));
13301345
id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
13311346
if (IS_ERR(id_priv) && *net_dev) {
@@ -1403,7 +1418,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
14031418
mutex_lock(&lock);
14041419
hlist_del(&id_priv->node);
14051420
if (hlist_empty(&bind_list->owners)) {
1406-
cma_ps_remove(bind_list->ps, bind_list->port);
1421+
cma_ps_remove(&init_net, bind_list->ps, bind_list->port);
14071422
kfree(bind_list);
14081423
}
14091424
mutex_unlock(&lock);
@@ -2693,7 +2708,7 @@ static int cma_alloc_port(enum rdma_port_space ps,
26932708
if (!bind_list)
26942709
return -ENOMEM;
26952710

2696-
ret = cma_ps_alloc(ps, bind_list, snum);
2711+
ret = cma_ps_alloc(&init_net, ps, bind_list, snum);
26972712
if (ret < 0)
26982713
goto err;
26992714

@@ -2718,7 +2733,7 @@ static int cma_alloc_any_port(enum rdma_port_space ps,
27182733
rover = prandom_u32() % remaining + low;
27192734
retry:
27202735
if (last_used_port != rover &&
2721-
!cma_ps_find(ps, (unsigned short)rover)) {
2736+
!cma_ps_find(&init_net, ps, (unsigned short)rover)) {
27222737
int ret = cma_alloc_port(ps, id_priv, rover);
27232738
/*
27242739
* Remember previously used port number in order to avoid
@@ -2784,7 +2799,7 @@ static int cma_use_port(enum rdma_port_space ps,
27842799
if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
27852800
return -EACCES;
27862801

2787-
bind_list = cma_ps_find(ps, snum);
2802+
bind_list = cma_ps_find(&init_net, ps, snum);
27882803
if (!bind_list) {
27892804
ret = cma_alloc_port(ps, id_priv, snum);
27902805
} else {
@@ -4004,6 +4019,35 @@ static const struct ibnl_client_cbs cma_cb_table[] = {
40044019
.module = THIS_MODULE },
40054020
};
40064021

4022+
static int cma_init_net(struct net *net)
4023+
{
4024+
struct cma_pernet *pernet = cma_pernet(net);
4025+
4026+
idr_init(&pernet->tcp_ps);
4027+
idr_init(&pernet->udp_ps);
4028+
idr_init(&pernet->ipoib_ps);
4029+
idr_init(&pernet->ib_ps);
4030+
4031+
return 0;
4032+
}
4033+
4034+
static void cma_exit_net(struct net *net)
4035+
{
4036+
struct cma_pernet *pernet = cma_pernet(net);
4037+
4038+
idr_destroy(&pernet->tcp_ps);
4039+
idr_destroy(&pernet->udp_ps);
4040+
idr_destroy(&pernet->ipoib_ps);
4041+
idr_destroy(&pernet->ib_ps);
4042+
}
4043+
4044+
static struct pernet_operations cma_pernet_operations = {
4045+
.init = cma_init_net,
4046+
.exit = cma_exit_net,
4047+
.id = &cma_pernet_id,
4048+
.size = sizeof(struct cma_pernet),
4049+
};
4050+
40074051
static int __init cma_init(void)
40084052
{
40094053
int ret;
@@ -4012,6 +4056,10 @@ static int __init cma_init(void)
40124056
if (!cma_wq)
40134057
return -ENOMEM;
40144058

4059+
ret = register_pernet_subsys(&cma_pernet_operations);
4060+
if (ret)
4061+
goto err_wq;
4062+
40154063
ib_sa_register_client(&sa_client);
40164064
rdma_addr_register_client(&addr_client);
40174065
register_netdevice_notifier(&cma_nb);
@@ -4029,6 +4077,7 @@ static int __init cma_init(void)
40294077
unregister_netdevice_notifier(&cma_nb);
40304078
rdma_addr_unregister_client(&addr_client);
40314079
ib_sa_unregister_client(&sa_client);
4080+
err_wq:
40324081
destroy_workqueue(cma_wq);
40334082
return ret;
40344083
}
@@ -4040,11 +4089,8 @@ static void __exit cma_cleanup(void)
40404089
unregister_netdevice_notifier(&cma_nb);
40414090
rdma_addr_unregister_client(&addr_client);
40424091
ib_sa_unregister_client(&sa_client);
4092+
unregister_pernet_subsys(&cma_pernet_operations);
40434093
destroy_workqueue(cma_wq);
4044-
idr_destroy(&tcp_ps);
4045-
idr_destroy(&udp_ps);
4046-
idr_destroy(&ipoib_ps);
4047-
idr_destroy(&ib_ps);
40484094
}
40494095

40504096
module_init(cma_init);

0 commit comments

Comments
 (0)