Skip to content

Commit 339ef61

Browse files
kcp-gitjfvogel
authored andcommitted
net/rds: Reduce RDS headers de-allocation time
After commit 10b43f1 ("net/rds: Use DMA memory pool allocation for rds_header"), the time to free the RDS headers at connection tear down becomes longer. At connection fail over time, hundreds of connections are shut down sequentially. A little extra time spent for each connection shutdown adds up. To reduce this fail over time, the headers free work is offloaded to a workqueue. Orabug: 30434704 Fixes: 10b43f1 ("net/rds: Use DMA memory pool allocation for rds_header") Signed-off-by: Ka-Cheong Poon <[email protected]> Reviewed-by: Håkon Bugge <[email protected]> Tested-by: Håkon Bugge <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]> Orabug: 30820081 UEK5 => UEK6 (cherry picked from commit 2d70f84) cherry-pick-repo=UEK/production/linux-uek.git Signed-off-by: Gerd Rausch <[email protected]> Reviewed-by: Sharon Liu <[email protected]>
1 parent b0fed0a commit 339ef61

File tree

3 files changed

+111
-30
lines changed

3 files changed

+111
-30
lines changed

net/rds/ib.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ static void rds_ib_dev_free_dev(struct rds_ib_device *rds_ibdev)
153153
ib_dereg_mr(rds_ibdev->mr);
154154
if (rds_ibdev->pd)
155155
ib_dealloc_pd(rds_ibdev->pd);
156+
/* Flush and destroy the header pool clean up work queue before
157+
* destroying the pool.
158+
*/
159+
if (rds_ibdev->rid_hdrs_pool_wq)
160+
destroy_workqueue(rds_ibdev->rid_hdrs_pool_wq);
156161
if (rds_ibdev->rid_hdrs_pool)
157162
dma_pool_destroy(rds_ibdev->rid_hdrs_pool);
158163
out:
@@ -619,6 +624,13 @@ void rds_ib_add_one(struct ib_device *device)
619624
if (!rds_ibdev->rid_hdrs_pool)
620625
goto put_dev;
621626

627+
rds_ibdev->rid_hdrs_pool_wq = alloc_workqueue("rds_pool_%s",
628+
WQ_UNBOUND |
629+
WQ_MEM_RECLAIM, 0,
630+
device->name);
631+
if (!rds_ibdev->rid_hdrs_pool_wq)
632+
goto put_dev;
633+
622634
rds_ibdev->vector_load = kzalloc(sizeof(int) *
623635
device->num_comp_vectors, GFP_KERNEL);
624636
if (!rds_ibdev->vector_load) {

net/rds/ib.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,26 @@ struct rds_ib_rx_work {
184184
struct rds_ib_connection *ic;
185185
};
186186

187+
/* Structure for the DMA headers pool deallocation work */
188+
struct rds_dma_hdrs_free_wk {
189+
struct work_struct rdhf_work;
190+
struct dma_pool *rdhf_pool; /* Pool for the headers. */
191+
192+
/* Info of headers for sending. */
193+
struct rds_header **rdhf_snd_hdrs;
194+
dma_addr_t *rdhf_snd_dma_addrs;
195+
u32 rdhf_snd_num_hdrs;
196+
197+
/* Info of headers for receiving. */
198+
struct rds_header **rdhf_rcv_hdrs;
199+
dma_addr_t *rdhf_rcv_dma_addrs;
200+
u32 rdhf_rcv_num_hdrs;
201+
202+
/* Info of the ACK header. */
203+
struct rds_header *rdhf_ack_rds_hdr;
204+
dma_addr_t rdhf_ack_dma_addr;
205+
};
206+
187207
struct rds_ib_connection {
188208

189209
struct list_head ib_node;
@@ -316,11 +336,6 @@ struct rds_ib_srq {
316336
};
317337

318338

319-
struct rds_ib_conn_drop_work {
320-
struct delayed_work work;
321-
struct rds_connection *conn;
322-
};
323-
324339
struct rds_ib_conn_destroy_work {
325340
struct delayed_work work;
326341
struct rds_connection *conn;
@@ -338,6 +353,7 @@ struct rds_ib_device {
338353
struct ib_device *dev;
339354
struct ib_pd *pd;
340355
struct dma_pool *rid_hdrs_pool; /* RDS headers DMA pool */
356+
struct workqueue_struct *rid_hdrs_pool_wq; /* Hdrs pool clean up wq */
341357

342358
bool use_fastreg;
343359
int fastreg_cq_vector;

net/rds/ib_cm.c

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,82 @@ void rds_dma_hdrs_free(struct dma_pool *pool, struct rds_header **hdrs,
804804
kvfree(dma_addrs);
805805
}
806806

807+
/* Worker function for freeing the DMA pool headers for sending and
808+
* receiving.
809+
*/
810+
static void rds_dma_hdrs_cleanup_worker(struct work_struct *work)
811+
{
812+
struct rds_dma_hdrs_free_wk *wk;
813+
struct dma_pool *pool;
814+
815+
wk = container_of(work, struct rds_dma_hdrs_free_wk, rdhf_work);
816+
817+
pool = wk->rdhf_pool;
818+
if (wk->rdhf_snd_hdrs)
819+
rds_dma_hdrs_free(pool, wk->rdhf_snd_hdrs,
820+
wk->rdhf_snd_dma_addrs,
821+
wk->rdhf_snd_num_hdrs);
822+
if (wk->rdhf_rcv_hdrs)
823+
rds_dma_hdrs_free(pool, wk->rdhf_rcv_hdrs,
824+
wk->rdhf_rcv_dma_addrs,
825+
wk->rdhf_rcv_num_hdrs);
826+
if (wk->rdhf_ack_rds_hdr)
827+
dma_pool_free(pool, wk->rdhf_ack_rds_hdr,
828+
wk->rdhf_ack_dma_addr);
829+
830+
kfree(wk);
831+
}
832+
833+
/* Free all the DMA pool headers associated with an RDS RDMA connection.
834+
*
835+
* @ic: the RDS RDMA connection
836+
*/
837+
static void rds_dma_hdrs_free_all(struct rds_ib_connection *ic)
838+
{
839+
struct rds_dma_hdrs_free_wk *wk;
840+
struct dma_pool *pool;
841+
842+
pool = ic->rds_ibdev->rid_hdrs_pool;
843+
844+
wk = kmalloc(sizeof(*wk), GFP_ATOMIC);
845+
if (wk) {
846+
wk->rdhf_pool = pool;
847+
848+
wk->rdhf_snd_hdrs = ic->i_send_hdrs;
849+
wk->rdhf_snd_dma_addrs = ic->i_send_hdrs_dma;
850+
wk->rdhf_snd_num_hdrs = ic->i_send_ring.w_nr;
851+
852+
wk->rdhf_rcv_hdrs = ic->i_recv_hdrs;
853+
wk->rdhf_rcv_dma_addrs = ic->i_recv_hdrs_dma;
854+
wk->rdhf_rcv_num_hdrs = ic->i_recv_ring.w_nr;
855+
856+
wk->rdhf_ack_rds_hdr = ic->i_ack;
857+
wk->rdhf_ack_dma_addr = ic->i_ack_dma;
858+
859+
INIT_WORK(&wk->rdhf_work, rds_dma_hdrs_cleanup_worker);
860+
queue_work(ic->rds_ibdev->rid_hdrs_pool_wq, &wk->rdhf_work);
861+
} else {
862+
if (ic->i_send_hdrs)
863+
rds_dma_hdrs_free(pool, ic->i_send_hdrs,
864+
ic->i_send_hdrs_dma,
865+
ic->i_send_ring.w_nr);
866+
if (ic->i_recv_hdrs)
867+
rds_dma_hdrs_free(pool, ic->i_recv_hdrs,
868+
ic->i_recv_hdrs_dma,
869+
ic->i_recv_ring.w_nr);
870+
if (ic->i_ack)
871+
dma_pool_free(pool, ic->i_ack, ic->i_ack_dma);
872+
}
873+
874+
ic->i_send_hdrs = NULL;
875+
ic->i_send_hdrs_dma = NULL;
876+
877+
ic->i_recv_hdrs = NULL;
878+
ic->i_recv_hdrs_dma = NULL;
879+
880+
ic->i_ack = NULL;
881+
}
882+
807883
/*
808884
* This needs to be very careful to not leave IS_ERR pointers around for
809885
* cleanup to trip over.
@@ -1586,32 +1662,9 @@ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp)
15861662
if (ic->i_cm_id->qp)
15871663
rdma_destroy_qp(ic->i_cm_id);
15881664

1665+
/* then free the resources that ib callbacks use */
15891666
if (ic->rds_ibdev) {
1590-
struct dma_pool *pool;
1591-
1592-
pool = ic->rds_ibdev->rid_hdrs_pool;
1593-
1594-
/* then free the resources that ib callbacks use */
1595-
if (ic->i_send_hdrs) {
1596-
rds_dma_hdrs_free(pool, ic->i_send_hdrs,
1597-
ic->i_send_hdrs_dma,
1598-
ic->i_send_ring.w_nr);
1599-
ic->i_send_hdrs = NULL;
1600-
ic->i_send_hdrs_dma = NULL;
1601-
}
1602-
1603-
if (ic->i_recv_hdrs) {
1604-
rds_dma_hdrs_free(pool, ic->i_recv_hdrs,
1605-
ic->i_recv_hdrs_dma,
1606-
ic->i_recv_ring.w_nr);
1607-
ic->i_recv_hdrs = NULL;
1608-
ic->i_recv_hdrs_dma = NULL;
1609-
}
1610-
1611-
if (ic->i_ack) {
1612-
dma_pool_free(pool, ic->i_ack, ic->i_ack_dma);
1613-
ic->i_ack = NULL;
1614-
}
1667+
rds_dma_hdrs_free_all(ic);
16151668
} else {
16161669
WARN_ON(ic->i_send_hdrs);
16171670
WARN_ON(ic->i_send_hdrs_dma);

0 commit comments

Comments
 (0)