Skip to content

Commit 2d70f84

Browse files
kcp-gitSomasundaram Krishnasamy
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]>
1 parent 48ec898 commit 2d70f84

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
@@ -131,6 +131,11 @@ static void rds_ib_dev_free_dev(struct rds_ib_device *rds_ibdev)
131131
ib_dereg_mr(rds_ibdev->mr);
132132
if (rds_ibdev->pd)
133133
ib_dealloc_pd(rds_ibdev->pd);
134+
/* Flush and destroy the header pool clean up work queue before
135+
* destroying the pool.
136+
*/
137+
if (rds_ibdev->rid_hdrs_pool_wq)
138+
destroy_workqueue(rds_ibdev->rid_hdrs_pool_wq);
134139
if (rds_ibdev->rid_hdrs_pool)
135140
dma_pool_destroy(rds_ibdev->rid_hdrs_pool);
136141
out:
@@ -593,6 +598,13 @@ void rds_ib_add_one(struct ib_device *device)
593598
if (!rds_ibdev->rid_hdrs_pool)
594599
goto put_dev;
595600

601+
rds_ibdev->rid_hdrs_pool_wq = alloc_workqueue("rds_pool_%s",
602+
WQ_UNBOUND |
603+
WQ_MEM_RECLAIM, 0,
604+
device->name);
605+
if (!rds_ibdev->rid_hdrs_pool_wq)
606+
goto put_dev;
607+
596608
rds_ibdev->vector_load = kzalloc(sizeof(int) *
597609
device->num_comp_vectors, GFP_KERNEL);
598610
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)