aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@sandisk.com>2016-09-26 15:58:49 -0400
committerDoug Ledford <dledford@redhat.com>2016-10-07 16:54:39 -0400
commit681cc3608355737c1effebc8145f95c8c3344bc3 (patch)
tree440c6dc95990989c80eaeac571a01c88efce3d7a
parent52bb8c626e0e5526c72b6ad17f1381f0bad283cc (diff)
IB/srp: Fix infinite loop when FMR sg[0].offset != 0
Avoid that mapping an sg-list in which the first element has a non-zero offset triggers an infinite loop when using FMR. This patch makes the FMR mapping code similar to that of ib_sg_to_pages(). Note: older Mellanox HCAs do not support non-zero offsets for FMR. See also commit 8c4037b501ac ("IB/srp: always avoid non-zero offsets into an FMR"). Reported-by: Alex Estrin <alex.estrin@intel.com> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: <stable@vger.kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 60031b9159d9..d980fb458ad4 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1402,7 +1402,9 @@ static int srp_map_sg_entry(struct srp_map_state *state,
1402 1402
1403 while (dma_len) { 1403 while (dma_len) {
1404 unsigned offset = dma_addr & ~dev->mr_page_mask; 1404 unsigned offset = dma_addr & ~dev->mr_page_mask;
1405 if (state->npages == dev->max_pages_per_mr || offset != 0) { 1405
1406 if (state->npages == dev->max_pages_per_mr ||
1407 (state->npages > 0 && offset != 0)) {
1406 ret = srp_map_finish_fmr(state, ch); 1408 ret = srp_map_finish_fmr(state, ch);
1407 if (ret) 1409 if (ret)
1408 return ret; 1410 return ret;
@@ -1419,12 +1421,12 @@ static int srp_map_sg_entry(struct srp_map_state *state,
1419 } 1421 }
1420 1422
1421 /* 1423 /*
1422 * If the last entry of the MR wasn't a full page, then we need to 1424 * If the end of the MR is not on a page boundary then we need to
1423 * close it out and start a new one -- we can only merge at page 1425 * close it out and start a new one -- we can only merge at page
1424 * boundaries. 1426 * boundaries.
1425 */ 1427 */
1426 ret = 0; 1428 ret = 0;
1427 if (len != dev->mr_page_size) 1429 if ((dma_addr & ~dev->mr_page_mask) != 0)
1428 ret = srp_map_finish_fmr(state, ch); 1430 ret = srp_map_finish_fmr(state, ch);
1429 return ret; 1431 return ret;
1430} 1432}