Skip to content

Commit fa20105

Browse files
Guy Shapirodledford
authored andcommitted
IB/cma: Add support for network namespaces
Add support for network namespaces in the ib_cma module. This is accomplished by: 1. Adding network namespace parameter for rdma_create_id. This parameter is used to populate the network namespace field in rdma_id_private. rdma_create_id keeps a reference on the network namespace. 2. Using the network namespace from the rdma_id instead of init_net inside of ib_cma, when listening on an ID and when looking for an ID for an incoming request. 3. Decrementing the reference count for the appropriate network namespace when calling rdma_destroy_id. In order to preserve the current behavior init_net is passed when calling from other modules. Signed-off-by: Guy Shapiro <[email protected]> Signed-off-by: Haggai Eran <[email protected]> Signed-off-by: Yotam Kenneth <[email protected]> Signed-off-by: Shachar Raindel <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 4be74b4 commit fa20105

File tree

14 files changed

+52
-34
lines changed

14 files changed

+52
-34
lines changed

drivers/infiniband/core/cma.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,8 @@ static int cma_disable_callback(struct rdma_id_private *id_priv,
600600
return 0;
601601
}
602602

603-
struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
603+
struct rdma_cm_id *rdma_create_id(struct net *net,
604+
rdma_cm_event_handler event_handler,
604605
void *context, enum rdma_port_space ps,
605606
enum ib_qp_type qp_type)
606607
{
@@ -624,7 +625,7 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
624625
INIT_LIST_HEAD(&id_priv->listen_list);
625626
INIT_LIST_HEAD(&id_priv->mc_list);
626627
get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
627-
id_priv->id.route.addr.dev_addr.net = &init_net;
628+
id_priv->id.route.addr.dev_addr.net = get_net(net);
628629

629630
return &id_priv->id;
630631
}
@@ -1278,7 +1279,7 @@ static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
12781279
cma_protocol_roce(&id_priv->id);
12791280

12801281
return !addr->dev_addr.bound_dev_if ||
1281-
(net_eq(dev_net(net_dev), &init_net) &&
1282+
(net_eq(dev_net(net_dev), addr->dev_addr.net) &&
12821283
addr->dev_addr.bound_dev_if == net_dev->ifindex);
12831284
}
12841285

@@ -1339,7 +1340,7 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
13391340
}
13401341
}
13411342

1342-
bind_list = cma_ps_find(&init_net,
1343+
bind_list = cma_ps_find(*net_dev ? dev_net(*net_dev) : &init_net,
13431344
rdma_ps_from_service_id(req.service_id),
13441345
cma_port_from_service_id(req.service_id));
13451346
id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
@@ -1411,14 +1412,15 @@ static void cma_cancel_operation(struct rdma_id_private *id_priv,
14111412
static void cma_release_port(struct rdma_id_private *id_priv)
14121413
{
14131414
struct rdma_bind_list *bind_list = id_priv->bind_list;
1415+
struct net *net = id_priv->id.route.addr.dev_addr.net;
14141416

14151417
if (!bind_list)
14161418
return;
14171419

14181420
mutex_lock(&lock);
14191421
hlist_del(&id_priv->node);
14201422
if (hlist_empty(&bind_list->owners)) {
1421-
cma_ps_remove(&init_net, bind_list->ps, bind_list->port);
1423+
cma_ps_remove(net, bind_list->ps, bind_list->port);
14221424
kfree(bind_list);
14231425
}
14241426
mutex_unlock(&lock);
@@ -1477,6 +1479,7 @@ void rdma_destroy_id(struct rdma_cm_id *id)
14771479
cma_deref_id(id_priv->id.context);
14781480

14791481
kfree(id_priv->id.route.path_rec);
1482+
put_net(id_priv->id.route.addr.dev_addr.net);
14801483
kfree(id_priv);
14811484
}
14821485
EXPORT_SYMBOL(rdma_destroy_id);
@@ -1607,7 +1610,8 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
16071610
ib_event->param.req_rcvd.primary_path->service_id;
16081611
int ret;
16091612

1610-
id = rdma_create_id(listen_id->event_handler, listen_id->context,
1613+
id = rdma_create_id(listen_id->route.addr.dev_addr.net,
1614+
listen_id->event_handler, listen_id->context,
16111615
listen_id->ps, ib_event->param.req_rcvd.qp_type);
16121616
if (IS_ERR(id))
16131617
return NULL;
@@ -1662,9 +1666,10 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
16621666
struct rdma_id_private *id_priv;
16631667
struct rdma_cm_id *id;
16641668
const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
1669+
struct net *net = listen_id->route.addr.dev_addr.net;
16651670
int ret;
16661671

1667-
id = rdma_create_id(listen_id->event_handler, listen_id->context,
1672+
id = rdma_create_id(net, listen_id->event_handler, listen_id->context,
16681673
listen_id->ps, IB_QPT_UD);
16691674
if (IS_ERR(id))
16701675
return NULL;
@@ -1901,7 +1906,8 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
19011906
return -ECONNABORTED;
19021907

19031908
/* Create a new RDMA id for the new IW CM ID */
1904-
new_cm_id = rdma_create_id(listen_id->id.event_handler,
1909+
new_cm_id = rdma_create_id(listen_id->id.route.addr.dev_addr.net,
1910+
listen_id->id.event_handler,
19051911
listen_id->id.context,
19061912
RDMA_PS_TCP, IB_QPT_RC);
19071913
if (IS_ERR(new_cm_id)) {
@@ -2029,12 +2035,13 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
20292035
{
20302036
struct rdma_id_private *dev_id_priv;
20312037
struct rdma_cm_id *id;
2038+
struct net *net = id_priv->id.route.addr.dev_addr.net;
20322039
int ret;
20332040

20342041
if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1))
20352042
return;
20362043

2037-
id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps,
2044+
id = rdma_create_id(net, cma_listen_handler, id_priv, id_priv->id.ps,
20382045
id_priv->id.qp_type);
20392046
if (IS_ERR(id))
20402047
return;
@@ -2708,7 +2715,8 @@ static int cma_alloc_port(enum rdma_port_space ps,
27082715
if (!bind_list)
27092716
return -ENOMEM;
27102717

2711-
ret = cma_ps_alloc(&init_net, ps, bind_list, snum);
2718+
ret = cma_ps_alloc(id_priv->id.route.addr.dev_addr.net, ps, bind_list,
2719+
snum);
27122720
if (ret < 0)
27132721
goto err;
27142722

@@ -2727,13 +2735,14 @@ static int cma_alloc_any_port(enum rdma_port_space ps,
27272735
static unsigned int last_used_port;
27282736
int low, high, remaining;
27292737
unsigned int rover;
2738+
struct net *net = id_priv->id.route.addr.dev_addr.net;
27302739

2731-
inet_get_local_port_range(&init_net, &low, &high);
2740+
inet_get_local_port_range(net, &low, &high);
27322741
remaining = (high - low) + 1;
27332742
rover = prandom_u32() % remaining + low;
27342743
retry:
27352744
if (last_used_port != rover &&
2736-
!cma_ps_find(&init_net, ps, (unsigned short)rover)) {
2745+
!cma_ps_find(net, ps, (unsigned short)rover)) {
27372746
int ret = cma_alloc_port(ps, id_priv, rover);
27382747
/*
27392748
* Remember previously used port number in order to avoid
@@ -2799,7 +2808,7 @@ static int cma_use_port(enum rdma_port_space ps,
27992808
if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
28002809
return -EACCES;
28012810

2802-
bind_list = cma_ps_find(&init_net, ps, snum);
2811+
bind_list = cma_ps_find(id_priv->id.route.addr.dev_addr.net, ps, snum);
28032812
if (!bind_list) {
28042813
ret = cma_alloc_port(ps, id_priv, snum);
28052814
} else {
@@ -2991,8 +3000,11 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
29913000
if (addr->sa_family == AF_INET)
29923001
id_priv->afonly = 1;
29933002
#if IS_ENABLED(CONFIG_IPV6)
2994-
else if (addr->sa_family == AF_INET6)
2995-
id_priv->afonly = init_net.ipv6.sysctl.bindv6only;
3003+
else if (addr->sa_family == AF_INET6) {
3004+
struct net *net = id_priv->id.route.addr.dev_addr.net;
3005+
3006+
id_priv->afonly = net->ipv6.sysctl.bindv6only;
3007+
}
29963008
#endif
29973009
}
29983010
ret = cma_get_port(id_priv);
@@ -3797,6 +3809,7 @@ static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id
37973809
dev_addr = &id_priv->id.route.addr.dev_addr;
37983810

37993811
if ((dev_addr->bound_dev_if == ndev->ifindex) &&
3812+
(net_eq(dev_net(ndev), dev_addr->net)) &&
38003813
memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) {
38013814
printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n",
38023815
ndev->name, &id_priv->id);
@@ -3822,9 +3835,6 @@ static int cma_netdev_callback(struct notifier_block *self, unsigned long event,
38223835
struct rdma_id_private *id_priv;
38233836
int ret = NOTIFY_DONE;
38243837

3825-
if (dev_net(ndev) != &init_net)
3826-
return NOTIFY_DONE;
3827-
38283838
if (event != NETDEV_BONDING_FAILOVER)
38293839
return NOTIFY_DONE;
38303840

drivers/infiniband/core/ucma.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,8 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
472472
return -ENOMEM;
473473

474474
ctx->uid = cmd.uid;
475-
ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
475+
ctx->cm_id = rdma_create_id(&init_net, ucma_event_handler, ctx, cmd.ps,
476+
qp_type);
476477
if (IS_ERR(ctx->cm_id)) {
477478
ret = PTR_ERR(ctx->cm_id);
478479
goto err1;

drivers/infiniband/ulp/iser/iser_verbs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ int iser_connect(struct iser_conn *iser_conn,
10171017
ib_conn->beacon.wr_id = ISER_BEACON_WRID;
10181018
ib_conn->beacon.opcode = IB_WR_SEND;
10191019

1020-
ib_conn->cma_id = rdma_create_id(iser_cma_handler,
1020+
ib_conn->cma_id = rdma_create_id(&init_net, iser_cma_handler,
10211021
(void *)iser_conn,
10221022
RDMA_PS_TCP, IB_QPT_RC);
10231023
if (IS_ERR(ib_conn->cma_id)) {

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3096,7 +3096,7 @@ isert_setup_id(struct isert_np *isert_np)
30963096
sa = (struct sockaddr *)&np->np_sockaddr;
30973097
isert_dbg("ksockaddr: %p, sa: %p\n", &np->np_sockaddr, sa);
30983098

3099-
id = rdma_create_id(isert_cma_handler, isert_np,
3099+
id = rdma_create_id(&init_net, isert_cma_handler, isert_np,
31003100
RDMA_PS_TCP, IB_QPT_RC);
31013101
if (IS_ERR(id)) {
31023102
isert_err("rdma_create_id() failed: %ld\n", PTR_ERR(id));

drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ extern kib_tunables_t kiblnd_tunables;
128128
IBLND_CREDIT_HIGHWATER_V1 : \
129129
*kiblnd_tunables.kib_peercredits_hiw) /* when eagerly to return credits */
130130

131-
#define kiblnd_rdma_create_id(cb, dev, ps, qpt) rdma_create_id(cb, dev, ps, qpt)
131+
#define kiblnd_rdma_create_id(cb, dev, ps, qpt) rdma_create_id(&init_net, \
132+
cb, dev, \
133+
ps, qpt)
132134

133135
static inline int
134136
kiblnd_concurrent_sends_v1(void)

include/rdma/rdma_cm.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,17 @@ struct rdma_cm_id {
160160
/**
161161
* rdma_create_id - Create an RDMA identifier.
162162
*
163+
* @net: The network namespace in which to create the new id.
163164
* @event_handler: User callback invoked to report events associated with the
164165
* returned rdma_id.
165166
* @context: User specified context associated with the id.
166167
* @ps: RDMA port space.
167168
* @qp_type: type of queue pair associated with the id.
169+
*
170+
* The id holds a reference on the network namespace until it is destroyed.
168171
*/
169-
struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
172+
struct rdma_cm_id *rdma_create_id(struct net *net,
173+
rdma_cm_event_handler event_handler,
170174
void *context, enum rdma_port_space ps,
171175
enum ib_qp_type qp_type);
172176

net/9p/trans_rdma.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,8 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args)
655655
return -ENOMEM;
656656

657657
/* Create the RDMA CM ID */
658-
rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP,
659-
IB_QPT_RC);
658+
rdma->cm_id = rdma_create_id(&init_net, p9_cm_event_handler, client,
659+
RDMA_PS_TCP, IB_QPT_RC);
660660
if (IS_ERR(rdma->cm_id))
661661
goto error;
662662

net/rds/ib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ static int rds_ib_laddr_check(struct net *net, __be32 addr)
317317
/* Create a CMA ID and try to bind it. This catches both
318318
* IB and iWARP capable NICs.
319319
*/
320-
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
320+
cm_id = rdma_create_id(&init_net, NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
321321
if (IS_ERR(cm_id))
322322
return PTR_ERR(cm_id);
323323

net/rds/ib_cm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ int rds_ib_conn_connect(struct rds_connection *conn)
565565

566566
/* XXX I wonder what affect the port space has */
567567
/* delegate cm event handler to rdma_transport */
568-
ic->i_cm_id = rdma_create_id(rds_rdma_cm_event_handler, conn,
568+
ic->i_cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler, conn,
569569
RDMA_PS_TCP, IB_QPT_RC);
570570
if (IS_ERR(ic->i_cm_id)) {
571571
ret = PTR_ERR(ic->i_cm_id);

net/rds/iw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static int rds_iw_laddr_check(struct net *net, __be32 addr)
223223
/* Create a CMA ID and try to bind it. This catches both
224224
* IB and iWARP capable NICs.
225225
*/
226-
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
226+
cm_id = rdma_create_id(&init_net, NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
227227
if (IS_ERR(cm_id))
228228
return PTR_ERR(cm_id);
229229

net/rds/iw_cm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ int rds_iw_conn_connect(struct rds_connection *conn)
524524

525525
/* XXX I wonder what affect the port space has */
526526
/* delegate cm event handler to rdma_transport */
527-
ic->i_cm_id = rdma_create_id(rds_rdma_cm_event_handler, conn,
527+
ic->i_cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler, conn,
528528
RDMA_PS_TCP, IB_QPT_RC);
529529
if (IS_ERR(ic->i_cm_id)) {
530530
ret = PTR_ERR(ic->i_cm_id);

net/rds/rdma_transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ static int rds_rdma_listen_init(void)
142142
struct rdma_cm_id *cm_id;
143143
int ret;
144144

145-
cm_id = rdma_create_id(rds_rdma_cm_event_handler, NULL, RDMA_PS_TCP,
146-
IB_QPT_RC);
145+
cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler, NULL,
146+
RDMA_PS_TCP, IB_QPT_RC);
147147
if (IS_ERR(cm_id)) {
148148
ret = PTR_ERR(cm_id);
149149
printk(KERN_ERR "RDS/RDMA: failed to setup listener, "

net/sunrpc/xprtrdma/svc_rdma_transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,8 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
692692
if (!cma_xprt)
693693
return ERR_PTR(-ENOMEM);
694694

695-
listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP,
696-
IB_QPT_RC);
695+
listen_id = rdma_create_id(&init_net, rdma_listen_handler, cma_xprt,
696+
RDMA_PS_TCP, IB_QPT_RC);
697697
if (IS_ERR(listen_id)) {
698698
ret = PTR_ERR(listen_id);
699699
dprintk("svcrdma: rdma_create_id failed = %d\n", ret);

net/sunrpc/xprtrdma/verbs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
432432

433433
init_completion(&ia->ri_done);
434434

435-
id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP, IB_QPT_RC);
435+
id = rdma_create_id(&init_net, rpcrdma_conn_upcall, xprt, RDMA_PS_TCP,
436+
IB_QPT_RC);
436437
if (IS_ERR(id)) {
437438
rc = PTR_ERR(id);
438439
dprintk("RPC: %s: rdma_create_id() failed %i\n",

0 commit comments

Comments
 (0)