Message ID | 565FA75E.7010100@sandisk.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
> Hello Sagi, > > Hmm ... why would it be unacceptable to return 0 if sg_nents == 0 ? > > Regarding which component to modify if mapping the first page fails: > for almost every kernel function I know a negative return value means > failure and a return value >= 0 means success. Hence my proposal to > change the return value of the ib_map_mr_sg() function if mapping the > first page fails. I'm fine with that. > > How about the patch below ? Looks fine. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> How about the patch below ? The patch looks good to me, but while we touch this area, how about throwing in a few cosmetic fixes as well? > - if (i && page_addr != dma_addr) { > + if (i && (page_addr != dma_addr || last_page_off != 0)) { > if (last_end_dma_addr != dma_addr) { Wo about we one or two sentences for each of the conditions here? > /* gap */ > - goto done; > - > + break; > } else if (last_page_off + dma_len <= mr->page_size) { > /* chunk this fragment with the last */ > mr->length += dma_len; It would be great to avoid the else clauses if we already to a break/continue/goto to make the code flow more clear, e.g. /* * Gap to the previous segment, we'll need to return * and use another FR to map the reminder. */ if (last_end_dma_addr != dma_addr) break; /* * See if this segment is contiguous to the * previous one and just merge it in that case. */ if (last_page_off + dma_len <= mr->page_size) { last_end_dma_addr += dma_len; last_page_off += dma_len; mr->length += dma_len; continue; } /* * New page-aligned segment to map: */ page_addr = last_page_addr + mr->page_size; dma_len -= mr->page_size - last_page_off; -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 043a60e..1972c50 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(ib_map_mr_sg); * @sg_nents: number of entries in sg * @set_page: driver page assignment function pointer * - * Core service helper for drivers to covert the largest + * Core service helper for drivers to convert the largest * prefix of given sg list to a page vector. The sg list * prefix converted is the prefix that meet the requirements * of ib_map_mr_sg. @@ -1533,7 +1533,7 @@ int ib_sg_to_pages(struct ib_mr *mr, u64 last_end_dma_addr = 0, last_page_addr = 0; unsigned int last_page_off = 0; u64 page_mask = ~((u64)mr->page_size - 1); - int i; + int i, ret; mr->iova = sg_dma_address(&sgl[0]); mr->length = 0; @@ -1544,11 +1544,10 @@ int ib_sg_to_pages(struct ib_mr *mr, u64 end_dma_addr = dma_addr + dma_len; u64 page_addr = dma_addr & page_mask; - if (i && page_addr != dma_addr) { + if (i && (page_addr != dma_addr || last_page_off != 0)) { if (last_end_dma_addr != dma_addr) { /* gap */ - goto done; - + break; } else if (last_page_off + dma_len <= mr->page_size) { /* chunk this fragment with the last */ mr->length += dma_len; @@ -1563,8 +1562,9 @@ int ib_sg_to_pages(struct ib_mr *mr, } do { - if (unlikely(set_page(mr, page_addr))) - goto done; + ret = set_page(mr, page_addr); + if (unlikely(ret < 0)) + return i ? : ret; page_addr += mr->page_size; } while (page_addr < end_dma_addr); @@ -1574,7 +1574,6 @@ int ib_sg_to_pages(struct ib_mr *mr, last_page_off = end_dma_addr & ~page_mask; } -done: return i; } EXPORT_SYMBOL(ib_sg_to_pages);