[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1487198500.122284398@decadent.org.uk>
Date: Wed, 15 Feb 2017 22:41:40 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org, "Doug Ledford" <dledford@...hat.com>,
"Alex Estrin" <alex.estrin@...el.com>,
"Bart Van Assche" <bart.vanassche@...disk.com>
Subject: [PATCH 3.16 101/306] IB/srp: Fix infinite loop when FMR
sg[0].offset != 0
3.16.40-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <bart.vanassche@...disk.com>
commit 681cc3608355737c1effebc8145f95c8c3344bc3 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 8c4037b501ac ("IB/srp: always avoid non-zero offsets
into an FMR").
Reported-by: Alex Estrin <alex.estrin@...el.com>
Signed-off-by: Bart Van Assche <bart.vanassche@...disk.com>
Signed-off-by: Doug Ledford <dledford@...hat.com>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
drivers/infiniband/ulp/srp/ib_srp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1310,7 +1310,9 @@ static int srp_map_sg_entry(struct srp_m
while (dma_len) {
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);
if (ret)
return ret;
@@ -1329,12 +1331,12 @@ static int srp_map_sg_entry(struct srp_m
}
/*
- * 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
* boundries.
*/
ret = 0;
- if (len != dev->mr_page_size) {
+ if ((dma_addr & ~dev->mr_page_mask) != 0) {
ret = srp_finish_mapping(state, target);
if (!ret)
srp_map_update_start(state, NULL, 0, 0);
Powered by blists - more mailing lists