Commit 00a05de9 authored by Bart Van Assche's avatar Bart Van Assche Committed by Ben Hutchings

IB/srp: Fix infinite loop when FMR sg[0].offset != 0

commit 681cc360 upstream.

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 8c4037b5 ("IB/srp: always avoid non-zero offsets
into an FMR").
Reported-by: default avatarAlex Estrin <alex.estrin@intel.com>
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 3c54629c
...@@ -1310,7 +1310,9 @@ static int srp_map_sg_entry(struct srp_map_state *state, ...@@ -1310,7 +1310,9 @@ static int srp_map_sg_entry(struct srp_map_state *state,
while (dma_len) { while (dma_len) {
unsigned offset = dma_addr & ~dev->mr_page_mask; unsigned offset = dma_addr & ~dev->mr_page_mask;
if (state->npages == dev->max_pages_per_mr || offset != 0) {
if (state->npages == dev->max_pages_per_mr ||
(state->npages > 0 && offset != 0)) {
ret = srp_finish_mapping(state, target); ret = srp_finish_mapping(state, target);
if (ret) if (ret)
return ret; return ret;
...@@ -1329,12 +1331,12 @@ static int srp_map_sg_entry(struct srp_map_state *state, ...@@ -1329,12 +1331,12 @@ static int srp_map_sg_entry(struct srp_map_state *state,
} }
/* /*
* If the last entry of the MR wasn't a full page, then we need to * If the end of the MR is not on a page boundary then we need to
* close it out and start a new one -- we can only merge at page * close it out and start a new one -- we can only merge at page
* boundries. * boundries.
*/ */
ret = 0; ret = 0;
if (len != dev->mr_page_size) { if ((dma_addr & ~dev->mr_page_mask) != 0) {
ret = srp_finish_mapping(state, target); ret = srp_finish_mapping(state, target);
if (!ret) if (!ret)
srp_map_update_start(state, NULL, 0, 0); srp_map_update_start(state, NULL, 0, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment