Skip to content

Commit 23f63db

Browse files
Wengang-oracleMukesh Kacker
authored andcommitted
rds: srq initialization and cleanup
RDS has the following two problem related to shared receive queues 1) srq initialization: When a new IB dev is registered to device_list, the .add methods of clients in client_list are called to do some initialization work. For RDS, rds_ib_add_one() is called. srq related things should be well initialized here since this is the last change before using srq. However, code only allocates memory and seems hope rds_ib_srqs_init() to initialize it later. But infact, rds_ib_srqs_init() is not called if the call path is not insmod of rds_rdma. 2) srq cleanup: When removing rds_rdma module, srqs for all rds_ib_device should be cleaned up. However, code only frees the rds_ib_device.srq memory and is not cleaning up memory pointed to by pointers embedded inside. This lead to resource leak. This patch fixes the above two problems. Orabug: 21795815 Signed-off-by: Wengang Wang <[email protected]> Reviewed-by: Chien Yen <[email protected]> Signed-off-by: Guangyu Sun <[email protected]> Signed-off-by: Mukesh Kacker <[email protected]>
1 parent 969bb4e commit 23f63db

File tree

3 files changed

+42
-59
lines changed

3 files changed

+42
-59
lines changed

net/rds/ib.c

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,10 @@ static void rds_ib_dev_free(struct work_struct *work)
217217
if (rds_ibdev->pd)
218218
ib_dealloc_pd(rds_ibdev->pd);
219219
}
220-
kfree(rds_ibdev->srq);
220+
if (rds_ibdev->srq) {
221+
rds_ib_srq_exit(rds_ibdev);
222+
kfree(rds_ibdev->srq);
223+
}
221224

222225
list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) {
223226
list_del(&i_ipaddr->list);
@@ -2170,13 +2173,12 @@ void rds_ib_add_one(struct ib_device *device)
21702173
goto put_dev;
21712174
}
21722175

2173-
rds_ibdev->srq = kmalloc(sizeof(struct rds_ib_srq), GFP_KERNEL);
2174-
if (!rds_ibdev->srq)
2175-
goto free_attr;
2176-
21772176
INIT_LIST_HEAD(&rds_ibdev->ipaddr_list);
21782177
INIT_LIST_HEAD(&rds_ibdev->conn_list);
21792178

2179+
if (rds_ib_srq_init(rds_ibdev))
2180+
goto put_dev;
2181+
21802182
down_write(&rds_ib_devices_lock);
21812183
list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices);
21822184
up_write(&rds_ib_devices_lock);
@@ -2622,33 +2624,27 @@ int rds_ib_init(void)
26222624
if (ret)
26232625
goto out;
26242626

2625-
ret = ib_register_client(&rds_ib_client);
2626-
if (ret)
2627-
goto out_fmr_exit;
2628-
26292627
ret = rds_ib_sysctl_init();
26302628
if (ret)
2631-
goto out_ibreg;
2629+
goto out_fmr_exit;
26322630

26332631
ret = rds_ib_recv_init();
26342632
if (ret)
26352633
goto out_sysctl;
26362634

2637-
ret = rds_ib_srqs_init();
2638-
if (ret) {
2639-
printk(KERN_ERR "RDS/IB: Failed to init SRQ\n");
2635+
ret = ib_register_client(&rds_ib_client);
2636+
if (ret)
26402637
goto out_recv;
2641-
}
26422638

26432639
rds_aux_wq = create_singlethread_workqueue("krdsd_aux");
26442640
if (!rds_aux_wq) {
26452641
printk(KERN_ERR "RDS/IB: failed to create aux workqueue\n");
2646-
goto out_srq;
2642+
goto out_ibreg;
26472643
}
26482644

26492645
ret = rds_trans_register(&rds_ib_transport);
26502646
if (ret)
2651-
goto out_srq;
2647+
goto out_ibreg;
26522648

26532649
rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
26542650

@@ -2657,7 +2653,7 @@ int rds_ib_init(void)
26572653
ret = rds_ib_ip_config_init();
26582654
if (ret) {
26592655
printk(KERN_ERR "RDS/IB: failed to init port\n");
2660-
goto out_srq;
2656+
goto out_ibreg;
26612657
}
26622658

26632659
rds_ib_ip_failover_groups_init();
@@ -2666,14 +2662,12 @@ int rds_ib_init(void)
26662662

26672663
goto out;
26682664

2669-
out_srq:
2670-
rds_ib_srqs_exit();
2665+
out_ibreg:
2666+
rds_ib_unregister_client();
26712667
out_recv:
26722668
rds_ib_recv_exit();
26732669
out_sysctl:
26742670
rds_ib_sysctl_exit();
2675-
out_ibreg:
2676-
rds_ib_unregister_client();
26772671
out_fmr_exit:
26782672
rds_ib_fmr_exit();
26792673
out:
@@ -2688,7 +2682,6 @@ void rds_ib_exit(void)
26882682
rds_ib_unregister_client();
26892683
rds_ib_destroy_nodev_conns();
26902684
rds_ib_sysctl_exit();
2691-
rds_ib_srqs_exit();
26922685
rds_ib_recv_exit();
26932686
flush_workqueue(rds_aux_wq);
26942687
destroy_workqueue(rds_aux_wq);

net/rds/ib.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,9 @@ extern struct workqueue_struct *rds_aux_wq;
535535
extern struct rds_transport rds_ib_transport;
536536
extern void rds_ib_add_one(struct ib_device *device);
537537
extern void rds_ib_remove_one(struct ib_device *device);
538+
void rds_ib_srq_exit(struct rds_ib_device *rds_ibdev);
539+
int rds_ib_srq_init(struct rds_ib_device *rds_ibdev);
540+
538541
struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device);
539542
void rds_ib_dev_put(struct rds_ib_device *rds_ibdev);
540543
extern struct ib_client rds_ib_client;
@@ -604,8 +607,6 @@ void rds_ib_fmr_exit(void);
604607
/* ib_recv.c */
605608
int rds_ib_recv_init(void);
606609
void rds_ib_recv_exit(void);
607-
int rds_ib_srqs_init(void);
608-
void rds_ib_srqs_exit(void);
609610
int rds_ib_recv(struct rds_connection *conn);
610611
int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
611612
void rds_ib_recv_free_caches(struct rds_ib_connection *ic);

net/rds/ib_recv.c

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -376,19 +376,23 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn,
376376
}
377377

378378
static void rds_ib_srq_clear_one(struct rds_ib_srq *srq,
379-
struct rds_ib_connection *ic,
380379
struct rds_ib_recv_work *recv)
381380
{
382381
if (recv->r_ibinc) {
383-
rds_inc_put(&recv->r_ibinc->ii_inc);
382+
if (recv->r_ic)
383+
rds_inc_put(&recv->r_ibinc->ii_inc);
384+
else
385+
kmem_cache_free(rds_ib_incoming_slab, recv->r_ibinc);
384386
recv->r_ibinc = NULL;
385387
}
386388
if (recv->r_frag) {
387389
ib_dma_unmap_sg(srq->rds_ibdev->dev, &recv->r_frag->f_sg,
388390
1, DMA_FROM_DEVICE);
389-
rds_ib_frag_free(ic, recv->r_frag);
391+
if (recv->r_ic)
392+
rds_ib_frag_free(recv->r_ic, recv->r_frag);
393+
else
394+
kmem_cache_free(rds_ib_frag_slab, recv->r_frag);
390395
recv->r_frag = NULL;
391-
recv->r_ic = ic;
392396
recv->r_posted = 0;
393397
}
394398
}
@@ -1342,7 +1346,7 @@ void rds_ib_srq_refill(struct work_struct *work)
13421346

13431347
for (wr = &cur->r_wr; wr; wr = wr->next) {
13441348
recv = container_of(wr, struct rds_ib_recv_work, r_wr);
1345-
rds_ib_srq_clear_one(srq, recv->r_ic, recv);
1349+
rds_ib_srq_clear_one(srq, recv);
13461350
}
13471351
printk(KERN_ERR "ib_post_srq_recv failed\n");
13481352
goto out;
@@ -1360,7 +1364,7 @@ void rds_ib_srq_refill(struct work_struct *work)
13601364

13611365
for (wr = &cur->r_wr; wr; wr = wr->next) {
13621366
recv = container_of(wr, struct rds_ib_recv_work, r_wr);
1363-
rds_ib_srq_clear_one(srq, recv->r_ic, recv);
1367+
rds_ib_srq_clear_one(srq, recv);
13641368
}
13651369
printk(KERN_ERR "ib_post_srq_recv failed\n");
13661370
goto out;
@@ -1413,7 +1417,7 @@ static void rds_ib_srq_clear_ring(struct rds_ib_device *rds_ibdev)
14131417

14141418
for (i = 0, recv = rds_ibdev->srq->s_recvs;
14151419
i < rds_ibdev->srq->s_n_wr; i++, recv++)
1416-
rds_ib_srq_clear_one(rds_ibdev->srq, recv->r_ic, recv);
1420+
rds_ib_srq_clear_one(rds_ibdev->srq, recv);
14171421
}
14181422

14191423

@@ -1507,6 +1511,19 @@ int rds_ib_srq_init(struct rds_ib_device *rds_ibdev)
15071511
}
15081512
};
15091513

1514+
/* This is called in two paths
1515+
* 1) during insmod of rds_rdma module
1516+
* 2) rds_rdma module is ready, a new ib_device added to kernel
1517+
*/
1518+
if (!rds_ib_srq_enabled)
1519+
return 0;
1520+
1521+
rds_ibdev->srq = kmalloc(sizeof(struct rds_ib_srq), GFP_KERNEL);
1522+
if (!rds_ibdev->srq) {
1523+
pr_warn("RDS: allocating srq failed\n");
1524+
return 1;
1525+
}
1526+
15101527
rds_ibdev->srq->rds_ibdev = rds_ibdev;
15111528

15121529
rds_ibdev->srq->s_n_wr = rds_ib_srq_max_wr - 1;
@@ -1554,23 +1571,6 @@ int rds_ib_srq_init(struct rds_ib_device *rds_ibdev)
15541571
return 0;
15551572
}
15561573

1557-
int rds_ib_srqs_init(void)
1558-
{
1559-
struct rds_ib_device *rds_ibdev;
1560-
int ret;
1561-
1562-
if (!rds_ib_srq_enabled)
1563-
return 0;
1564-
1565-
list_for_each_entry(rds_ibdev, &rds_ib_devices, list) {
1566-
ret = rds_ib_srq_init(rds_ibdev);
1567-
if (ret)
1568-
return ret;
1569-
}
1570-
1571-
return 0;
1572-
}
1573-
15741574
void rds_ib_srq_exit(struct rds_ib_device *rds_ibdev)
15751575
{
15761576
int ret;
@@ -1592,14 +1592,3 @@ void rds_ib_srq_exit(struct rds_ib_device *rds_ibdev)
15921592
rds_ibdev->srq->s_recvs = NULL;
15931593
}
15941594

1595-
void rds_ib_srqs_exit(void)
1596-
{
1597-
struct rds_ib_device *rds_ibdev;
1598-
1599-
if (!rds_ib_srq_enabled)
1600-
return;
1601-
1602-
list_for_each_entry(rds_ibdev, &rds_ib_devices, list) {
1603-
rds_ib_srq_exit(rds_ibdev);
1604-
}
1605-
}

0 commit comments

Comments
 (0)