aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndy Grover <andy.grover@oracle.com>2010-05-24 23:28:49 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:15:21 -0400
commit3427e854e1a0e76be8b3d75fc0fa878f59b43693 (patch)
treecc0bb1c074612cfd6634ac6a4fa9c92709fa185a /net
parent0b088e003ccf316a76c51be5dec2d70b93be3be8 (diff)
RDS: Assume recv->r_frag is always NULL in refill_one()
refill_one() should never be called on a recv struct that doesn't need a new r_frag allocated. Add a WARN and remove conditional around r_frag alloc code. Also, add a comment to explain why r_ibinc may or may not need refilling. Signed-off-by: Andy Grover <andy.grover@oracle.com>
Diffstat (limited to 'net')
-rw-r--r--net/rds/ib_recv.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index f6dbf16e0741..5c7e6acf7c60 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -126,6 +126,10 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn,
126 struct ib_sge *sge; 126 struct ib_sge *sge;
127 int ret = -ENOMEM; 127 int ret = -ENOMEM;
128 128
129 /*
130 * ibinc was taken from recv if recv contained the start of a message.
131 * recvs that were continuations will still have this allocated.
132 */
129 if (!recv->r_ibinc) { 133 if (!recv->r_ibinc) {
130 if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { 134 if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) {
131 rds_ib_stats_inc(s_ib_rx_alloc_limit); 135 rds_ib_stats_inc(s_ib_rx_alloc_limit);
@@ -140,19 +144,18 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn,
140 rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); 144 rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr);
141 } 145 }
142 146
143 if (!recv->r_frag) { 147 WARN_ON(recv->r_frag); /* leak! */
144 recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); 148 recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT);
145 if (!recv->r_frag) 149 if (!recv->r_frag)
146 goto out; 150 goto out;
147 INIT_LIST_HEAD(&recv->r_frag->f_item); 151 INIT_LIST_HEAD(&recv->r_frag->f_item);
148 sg_init_table(&recv->r_frag->f_sg, 1); 152 sg_init_table(&recv->r_frag->f_sg, 1);
149 ret = rds_page_remainder_alloc(&recv->r_frag->f_sg, 153 ret = rds_page_remainder_alloc(&recv->r_frag->f_sg,
150 RDS_FRAG_SIZE, GFP_NOWAIT); 154 RDS_FRAG_SIZE, GFP_NOWAIT);
151 if (ret) { 155 if (ret) {
152 kmem_cache_free(rds_ib_frag_slab, recv->r_frag); 156 kmem_cache_free(rds_ib_frag_slab, recv->r_frag);
153 recv->r_frag = NULL; 157 recv->r_frag = NULL;
154 goto out; 158 goto out;
155 }
156 } 159 }
157 160
158 ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 161 ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg,