Message ID | 1414145922-26042-4-git-send-email-laurent.pinchart+renesas@ideasonboard.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
On Fri, Oct 24 2014, Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote: > Commit 95b0e655f914 ("ARM: mm: don't limit default CMA region only to > low memory") extended CMA memory reservation to allow usage of high > memory. It relied on commit f7426b983a6a ("mm: cma: adjust address limit > to avoid hitting low/high memory boundary") to ensure that the reserved > block never crossed the low/high memory boundary. While the > implementation correctly lowered the limit, it failed to consider the > case where the base..limit range crossed the low/high memory boundary > with enough space on each side to reserve the requested size on either > low or high memory. > > Rework the base and limit adjustment to fix the problem. The function > now starts by rejecting the reservation altogether for fixed > reservations that cross the boundary, tries to reserve from high memory > first and then falls back to low memory. > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Friday 24 October 2014 18:26:58 Michal Nazarewicz wrote: > On Fri, Oct 24 2014, Laurent Pinchart wrote: > > Commit 95b0e655f914 ("ARM: mm: don't limit default CMA region only to > > low memory") extended CMA memory reservation to allow usage of high > > memory. It relied on commit f7426b983a6a ("mm: cma: adjust address limit > > to avoid hitting low/high memory boundary") to ensure that the reserved > > block never crossed the low/high memory boundary. While the > > implementation correctly lowered the limit, it failed to consider the > > case where the base..limit range crossed the low/high memory boundary > > with enough space on each side to reserve the requested size on either > > low or high memory. > > > > Rework the base and limit adjustment to fix the problem. The function > > now starts by rejecting the reservation altogether for fixed > > reservations that cross the boundary, tries to reserve from high memory > > first and then falls back to low memory. > > > > Signed-off-by: Laurent Pinchart > > <laurent.pinchart+renesas@ideasonboard.com> > > Acked-by: Michal Nazarewicz <mina86@mina86.com> Thank you. Can we get this series merged in v3.18-rc ?
On Sun, Oct 26, 2014 at 02:43:52PM +0200, Laurent Pinchart wrote: > On Friday 24 October 2014 18:26:58 Michal Nazarewicz wrote: > > On Fri, Oct 24 2014, Laurent Pinchart wrote: > > > Commit 95b0e655f914 ("ARM: mm: don't limit default CMA region only to > > > low memory") extended CMA memory reservation to allow usage of high > > > memory. It relied on commit f7426b983a6a ("mm: cma: adjust address limit > > > to avoid hitting low/high memory boundary") to ensure that the reserved > > > block never crossed the low/high memory boundary. While the > > > implementation correctly lowered the limit, it failed to consider the > > > case where the base..limit range crossed the low/high memory boundary > > > with enough space on each side to reserve the requested size on either > > > low or high memory. > > > > > > Rework the base and limit adjustment to fix the problem. The function > > > now starts by rejecting the reservation altogether for fixed > > > reservations that cross the boundary, tries to reserve from high memory > > > first and then falls back to low memory. > > > > > > Signed-off-by: Laurent Pinchart > > > <laurent.pinchart+renesas@ideasonboard.com> > > > > Acked-by: Michal Nazarewicz <mina86@mina86.com> > > Thank you. Can we get this series merged in v3.18-rc ? Hello, You'd better to resend whole series to Andrew. Thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-sh" 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/mm/cma.c b/mm/cma.c index 62a5dccc3fb8..c30a6edee65c 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -253,23 +253,24 @@ int __init cma_declare_contiguous(phys_addr_t base, return -EINVAL; /* - * adjust limit to avoid crossing low/high memory boundary for - * automatically allocated regions + * If allocating at a fixed base the request region must not cross the + * low/high memory boundary. */ - if (((limit == 0 || limit > memblock_end) && - (memblock_end - size < highmem_start && - memblock_end > highmem_start)) || - (!fixed && limit > highmem_start && limit - size < highmem_start)) { - limit = highmem_start; - } - - if (fixed && base < highmem_start && base+size > highmem_start) { + if (fixed && base < highmem_start && base + size > highmem_start) { ret = -EINVAL; pr_err("Region at %08lx defined on low/high memory boundary (%08lx)\n", (unsigned long)base, (unsigned long)highmem_start); goto err; } + /* + * If the limit is unspecified or above the memblock end, its effective + * value will be the memblock end. Set it explicitly to simplify further + * checks. + */ + if (limit == 0 || limit > memblock_end) + limit = memblock_end; + /* Reserve memory */ if (fixed) { if (memblock_is_region_reserved(base, size) || @@ -278,14 +279,30 @@ int __init cma_declare_contiguous(phys_addr_t base, goto err; } } else { - phys_addr_t addr = memblock_alloc_range(size, alignment, base, - limit); + phys_addr_t addr = 0; + + /* + * All pages in the reserved area must come from the same zone. + * If the requested region crosses the low/high memory boundary, + * try allocating from high memory first and fall back to low + * memory in case of failure. + */ + if (base < highmem_start && limit > highmem_start) { + addr = memblock_alloc_range(size, alignment, + highmem_start, limit); + limit = highmem_start; + } + if (!addr) { - ret = -ENOMEM; - goto err; - } else { - base = addr; + addr = memblock_alloc_range(size, alignment, base, + limit); + if (!addr) { + ret = -ENOMEM; + goto err; + } } + + base = addr; } ret = cma_init_reserved_mem(base, size, order_per_bit, res_cma);
Commit 95b0e655f914 ("ARM: mm: don't limit default CMA region only to low memory") extended CMA memory reservation to allow usage of high memory. It relied on commit f7426b983a6a ("mm: cma: adjust address limit to avoid hitting low/high memory boundary") to ensure that the reserved block never crossed the low/high memory boundary. While the implementation correctly lowered the limit, it failed to consider the case where the base..limit range crossed the low/high memory boundary with enough space on each side to reserve the requested size on either low or high memory. Rework the base and limit adjustment to fix the problem. The function now starts by rejecting the reservation altogether for fixed reservations that cross the boundary, tries to reserve from high memory first and then falls back to low memory. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> --- mm/cma.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-)