diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/infiniband/core/verbs.c | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'drivers/infiniband/core/verbs.c')
-rw-r--r-- | drivers/infiniband/core/verbs.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 043a60ee6836..545906dec26d 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
@@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(ib_map_mr_sg); | |||
1516 | * @sg_nents: number of entries in sg | 1516 | * @sg_nents: number of entries in sg |
1517 | * @set_page: driver page assignment function pointer | 1517 | * @set_page: driver page assignment function pointer |
1518 | * | 1518 | * |
1519 | * Core service helper for drivers to covert the largest | 1519 | * Core service helper for drivers to convert the largest |
1520 | * prefix of given sg list to a page vector. The sg list | 1520 | * prefix of given sg list to a page vector. The sg list |
1521 | * prefix converted is the prefix that meet the requirements | 1521 | * prefix converted is the prefix that meet the requirements |
1522 | * of ib_map_mr_sg. | 1522 | * of ib_map_mr_sg. |
@@ -1533,7 +1533,7 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
1533 | u64 last_end_dma_addr = 0, last_page_addr = 0; | 1533 | u64 last_end_dma_addr = 0, last_page_addr = 0; |
1534 | unsigned int last_page_off = 0; | 1534 | unsigned int last_page_off = 0; |
1535 | u64 page_mask = ~((u64)mr->page_size - 1); | 1535 | u64 page_mask = ~((u64)mr->page_size - 1); |
1536 | int i; | 1536 | int i, ret; |
1537 | 1537 | ||
1538 | mr->iova = sg_dma_address(&sgl[0]); | 1538 | mr->iova = sg_dma_address(&sgl[0]); |
1539 | mr->length = 0; | 1539 | mr->length = 0; |
@@ -1544,27 +1544,29 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
1544 | u64 end_dma_addr = dma_addr + dma_len; | 1544 | u64 end_dma_addr = dma_addr + dma_len; |
1545 | u64 page_addr = dma_addr & page_mask; | 1545 | u64 page_addr = dma_addr & page_mask; |
1546 | 1546 | ||
1547 | if (i && page_addr != dma_addr) { | 1547 | /* |
1548 | if (last_end_dma_addr != dma_addr) { | 1548 | * For the second and later elements, check whether either the |
1549 | /* gap */ | 1549 | * end of element i-1 or the start of element i is not aligned |
1550 | goto done; | 1550 | * on a page boundary. |
1551 | 1551 | */ | |
1552 | } else if (last_page_off + dma_len <= mr->page_size) { | 1552 | if (i && (last_page_off != 0 || page_addr != dma_addr)) { |
1553 | /* chunk this fragment with the last */ | 1553 | /* Stop mapping if there is a gap. */ |
1554 | mr->length += dma_len; | 1554 | if (last_end_dma_addr != dma_addr) |
1555 | last_end_dma_addr += dma_len; | 1555 | break; |
1556 | last_page_off += dma_len; | 1556 | |
1557 | continue; | 1557 | /* |
1558 | } else { | 1558 | * Coalesce this element with the last. If it is small |
1559 | /* map starting from the next page */ | 1559 | * enough just update mr->length. Otherwise start |
1560 | page_addr = last_page_addr + mr->page_size; | 1560 | * mapping from the next page. |
1561 | dma_len -= mr->page_size - last_page_off; | 1561 | */ |
1562 | } | 1562 | goto next_page; |
1563 | } | 1563 | } |
1564 | 1564 | ||
1565 | do { | 1565 | do { |
1566 | if (unlikely(set_page(mr, page_addr))) | 1566 | ret = set_page(mr, page_addr); |
1567 | goto done; | 1567 | if (unlikely(ret < 0)) |
1568 | return i ? : ret; | ||
1569 | next_page: | ||
1568 | page_addr += mr->page_size; | 1570 | page_addr += mr->page_size; |
1569 | } while (page_addr < end_dma_addr); | 1571 | } while (page_addr < end_dma_addr); |
1570 | 1572 | ||
@@ -1574,7 +1576,6 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
1574 | last_page_off = end_dma_addr & ~page_mask; | 1576 | last_page_off = end_dma_addr & ~page_mask; |
1575 | } | 1577 | } |
1576 | 1578 | ||
1577 | done: | ||
1578 | return i; | 1579 | return i; |
1579 | } | 1580 | } |
1580 | EXPORT_SYMBOL(ib_sg_to_pages); | 1581 | EXPORT_SYMBOL(ib_sg_to_pages); |