Skip to content

Commit 2559429

Browse files
Steve WiseJ. Bruce Fields
authored andcommitted
svcrdma: send_write() must not overflow the device's max sge
Function send_write() must stop creating sges when it reaches the device max and return the amount sent in the RDMA Write to the caller. Signed-off-by: Steve Wise <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
1 parent a46cb7f commit 2559429

File tree

1 file changed

+15
-24
lines changed

1 file changed

+15
-24
lines changed

net/sunrpc/xprtrdma/svc_rdma_sendto.c

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
192192
xdr_sge_no++;
193193
BUG_ON(xdr_sge_no > vec->count);
194194
bc -= sge_bytes;
195+
if (sge_no == xprt->sc_max_sge)
196+
break;
195197
}
196198

197199
/* Prepare WRITE WR */
@@ -209,7 +211,7 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
209211
atomic_inc(&rdma_stat_write);
210212
if (svc_rdma_send(xprt, &write_wr))
211213
goto err;
212-
return 0;
214+
return write_len - bc;
213215
err:
214216
svc_rdma_unmap_dma(ctxt);
215217
svc_rdma_put_context(ctxt, 0);
@@ -225,7 +227,6 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
225227
{
226228
u32 xfer_len = rqstp->rq_res.page_len + rqstp->rq_res.tail[0].iov_len;
227229
int write_len;
228-
int max_write;
229230
u32 xdr_off;
230231
int chunk_off;
231232
int chunk_no;
@@ -239,8 +240,6 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
239240
res_ary = (struct rpcrdma_write_array *)
240241
&rdma_resp->rm_body.rm_chunks[1];
241242

242-
max_write = xprt->sc_max_sge * PAGE_SIZE;
243-
244243
/* Write chunks start at the pagelist */
245244
for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0;
246245
xfer_len && chunk_no < arg_ary->wc_nchunks;
@@ -260,23 +259,21 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
260259
write_len);
261260
chunk_off = 0;
262261
while (write_len) {
263-
int this_write;
264-
this_write = min(write_len, max_write);
265262
ret = send_write(xprt, rqstp,
266263
ntohl(arg_ch->rs_handle),
267264
rs_offset + chunk_off,
268265
xdr_off,
269-
this_write,
266+
write_len,
270267
vec);
271-
if (ret) {
268+
if (ret <= 0) {
272269
dprintk("svcrdma: RDMA_WRITE failed, ret=%d\n",
273270
ret);
274271
return -EIO;
275272
}
276-
chunk_off += this_write;
277-
xdr_off += this_write;
278-
xfer_len -= this_write;
279-
write_len -= this_write;
273+
chunk_off += ret;
274+
xdr_off += ret;
275+
xfer_len -= ret;
276+
write_len -= ret;
280277
}
281278
}
282279
/* Update the req with the number of chunks actually used */
@@ -293,7 +290,6 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
293290
{
294291
u32 xfer_len = rqstp->rq_res.len;
295292
int write_len;
296-
int max_write;
297293
u32 xdr_off;
298294
int chunk_no;
299295
int chunk_off;
@@ -311,8 +307,6 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
311307
res_ary = (struct rpcrdma_write_array *)
312308
&rdma_resp->rm_body.rm_chunks[2];
313309

314-
max_write = xprt->sc_max_sge * PAGE_SIZE;
315-
316310
/* xdr offset starts at RPC message */
317311
nchunks = ntohl(arg_ary->wc_nchunks);
318312
for (xdr_off = 0, chunk_no = 0;
@@ -330,24 +324,21 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
330324
write_len);
331325
chunk_off = 0;
332326
while (write_len) {
333-
int this_write;
334-
335-
this_write = min(write_len, max_write);
336327
ret = send_write(xprt, rqstp,
337328
ntohl(ch->rs_handle),
338329
rs_offset + chunk_off,
339330
xdr_off,
340-
this_write,
331+
write_len,
341332
vec);
342-
if (ret) {
333+
if (ret <= 0) {
343334
dprintk("svcrdma: RDMA_WRITE failed, ret=%d\n",
344335
ret);
345336
return -EIO;
346337
}
347-
chunk_off += this_write;
348-
xdr_off += this_write;
349-
xfer_len -= this_write;
350-
write_len -= this_write;
338+
chunk_off += ret;
339+
xdr_off += ret;
340+
xfer_len -= ret;
341+
write_len -= ret;
351342
}
352343
}
353344
/* Update the req with the number of chunks actually used */

0 commit comments

Comments
 (0)