Skip to content

Commit 942d5a3

Browse files
Wei Lin GuaySomasundaram Krishnasamy
authored andcommitted
net/rds: reduce memory footprint during ib_post_recv in IB transport
The RDS IB large fragment size feature requires order 2 memory allocations and it introduces memory pressure in the allocation system. Thus, this patch implements large fragment size support in ib_post_recv with N sge. As of today, RDS has an assumption that each IB received work request has only two SGEs. This patch removes this assumption and uses various SGE to support large fragment size. Orabug: 27339270 Signed-off-by: Wei Lin Guay <[email protected]> Reviewed-by: Håkon Bugge <[email protected]> Tested-by: Shih-Yu Huang <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> (cherry picked from commit 05af55886c8f3e092c2f222dd0ed73dbdfe59de5) Compilation errors: net/rds/ib_cm.c Commit 7d76b09d2274 (“net/rds Making RDS compile with 4.14 APIs (untested) & dropping iWarp") renamed "attr" to "qp_attr". Had to fix. net/rds/ib_recv.{ch} Commit d45c268a22ca ("RDS: make sure we post recv buffers") changes the signature and introduces "int can_wait". Reworked that to become equal upstream. The cherry picked commit did also include the fix in 9bf627b ("rds: ib: Fix NULL pointer dereference in debug code"), hence, had to remove the rdsdebug() call after ib_post_recv(). (cherry picked from commit bacbc2db34068892f6a1585801562227edee0b44) (cherry picked from commit 30650f2d7475db8865a40541af0017a5b7202baa) Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 8301483 commit 942d5a3

File tree

4 files changed

+159
-91
lines changed

4 files changed

+159
-91
lines changed

net/rds/ib.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,32 +2831,37 @@ int rds_ib_inc_to_skb(struct rds_incoming *inc, struct sk_buff *skb)
28312831
int i;
28322832
struct rds_ib_incoming *ibinc;
28332833
struct rds_page_frag *ibfrag;
2834+
struct scatterlist *sg;
28342835

28352836
/* pull out initial pointers */
28362837
ibinc = container_of(inc, struct rds_ib_incoming, ii_inc);
28372838
ibfrag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item);
28382839
len = be32_to_cpu(inc->i_hdr.h_len);
2840+
sg = ibfrag->f_sg;
28392841
slen = len;
28402842
i = 0;
28412843

28422844
/* run through the entire ib fragment list and save off the buffers */
28432845
while (NULL != ibfrag && slen > 0) {
28442846
/* one to one mapping of frags to sg structures */
28452847
frag = &skb_shinfo(skb)->frags[i];
2846-
28472848
/* save off all the sg pieces to the skb frags we are creating */
2848-
frag->size = ibfrag->f_sg.length;
2849-
frag->page_offset = ibfrag->f_sg.offset;
2850-
frag->page.p = sg_page(&ibfrag->f_sg);
2849+
frag->size = sg->length;
2850+
frag->page_offset = sg->offset;
2851+
frag->page.p = sg_page(sg);
28512852

28522853
/* AA: do we need to bump up the page reference */
28532854
/* get_page(frag->page); */
28542855

28552856
/* dec the amount of data we are consuming */
28562857
slen -= frag->size;
28572858

2858-
/* bump to the next entry */
2859-
ibfrag = list_entry(ibfrag->f_item.next, struct rds_page_frag, f_item);
2859+
sg = sg_next(sg);
2860+
if (!sg) {
2861+
/* bump to the next entry */
2862+
ibfrag = list_entry(ibfrag->f_item.next, struct rds_page_frag, f_item);
2863+
sg = ibfrag->f_sg;
2864+
}
28602865
i++;
28612866

28622867
/* for now we will only have a single chain of fragments in the skb */

net/rds/ib.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050

5151
#define RDS_WC_MAX 32
5252

53+
#define NUM_RDS_RECV_SG (PAGE_ALIGN(RDS_MAX_FRAG_SIZE) / PAGE_SIZE)
54+
5355
#define RDS_IB_CLEAN_CACHE 1
5456

5557
#define RDS_IB_DEFAULT_FREG_PORT_NUM 1
@@ -65,7 +67,7 @@ extern struct list_head rds_ib_devices;
6567
struct rds_page_frag {
6668
struct list_head f_item;
6769
struct list_head f_cache_entry;
68-
struct scatterlist f_sg;
70+
struct scatterlist f_sg[NUM_RDS_RECV_SG];
6971
};
7072

7173
struct rds_ib_incoming {
@@ -114,7 +116,7 @@ struct rds_ib_recv_work {
114116
struct rds_ib_incoming *r_ibinc;
115117
struct rds_page_frag *r_frag;
116118
struct ib_recv_wr r_wr;
117-
struct ib_sge r_sge[2];
119+
struct ib_sge r_sge[RDS_IB_MAX_SGE];
118120
struct rds_ib_connection *r_ic;
119121
int r_posted;
120122
};
@@ -629,7 +631,7 @@ int rds_ib_recv_path(struct rds_conn_path *cp);
629631
int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
630632
void rds_ib_recv_free_caches(struct rds_ib_connection *ic);
631633
void rds_ib_recv_rebuild_caches(struct rds_ib_connection *ic);
632-
void rds_ib_recv_refill(struct rds_connection *conn, int prefill, int can_wait);
634+
void rds_ib_recv_refill(struct rds_connection *conn, int prefill, gfp_t gfp);
633635
void rds_ib_inc_free(struct rds_incoming *inc);
634636
int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
635637
void rds_ib_recv_cqe_handler(struct rds_ib_connection *ic,

net/rds/ib_cm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
767767
qp_attr.cap.max_send_wr = ic->i_send_ring.w_nr + 1 + mr_reg;
768768
qp_attr.cap.max_recv_wr = ic->i_recv_ring.w_nr + 1;
769769
qp_attr.cap.max_send_sge = rds_ibdev->max_sge;
770-
qp_attr.cap.max_recv_sge = RDS_IB_RECV_SGE;
770+
qp_attr.cap.max_recv_sge = rds_ibdev->max_sge;
771771
qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
772772
qp_attr.qp_type = IB_QPT_RC;
773773
qp_attr.send_cq = ic->i_scq;

0 commit comments

Comments
 (0)