OSDN Git Service

Merge tag 'driver-core-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[uclinux-h8/linux.git] / mm / cma.c
index bc9ca8f..eaa4b5c 100644 (file)
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -131,8 +131,10 @@ not_in_zone:
        bitmap_free(cma->bitmap);
 out_error:
        /* Expose all pages to the buddy, they are useless for CMA. */
-       for (pfn = base_pfn; pfn < base_pfn + cma->count; pfn++)
-               free_reserved_page(pfn_to_page(pfn));
+       if (!cma->reserve_pages_on_error) {
+               for (pfn = base_pfn; pfn < base_pfn + cma->count; pfn++)
+                       free_reserved_page(pfn_to_page(pfn));
+       }
        totalcma_pages -= cma->count;
        cma->count = 0;
        pr_err("CMA area %s could not be activated\n", cma->name);
@@ -150,6 +152,11 @@ static int __init cma_init_reserved_areas(void)
 }
 core_initcall(cma_init_reserved_areas);
 
+void __init cma_reserve_pages_on_error(struct cma *cma)
+{
+       cma->reserve_pages_on_error = true;
+}
+
 /**
  * cma_init_reserved_mem() - create custom contiguous area from reserved memory
  * @base: Base address of the reserved area
@@ -168,7 +175,6 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
                                 struct cma **res_cma)
 {
        struct cma *cma;
-       phys_addr_t alignment;
 
        /* Sanity checks */
        if (cma_area_count == ARRAY_SIZE(cma_areas)) {
@@ -179,15 +185,12 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
        if (!size || !memblock_is_region_reserved(base, size))
                return -EINVAL;
 
-       /* ensure minimal alignment required by mm core */
-       alignment = PAGE_SIZE <<
-                       max_t(unsigned long, MAX_ORDER - 1, pageblock_order);
-
        /* alignment should be aligned with order_per_bit */
-       if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit))
+       if (!IS_ALIGNED(CMA_MIN_ALIGNMENT_PAGES, 1 << order_per_bit))
                return -EINVAL;
 
-       if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size)
+       /* ensure minimal alignment required by mm core */
+       if (!IS_ALIGNED(base | size, CMA_MIN_ALIGNMENT_BYTES))
                return -EINVAL;
 
        /*
@@ -262,14 +265,8 @@ int __init cma_declare_contiguous_nid(phys_addr_t base,
        if (alignment && !is_power_of_2(alignment))
                return -EINVAL;
 
-       /*
-        * Sanitise input arguments.
-        * Pages both ends in CMA area could be merged into adjacent unmovable
-        * migratetype page by page allocator's buddy algorithm. In the case,
-        * you couldn't get a contiguous memory, which is not what we want.
-        */
-       alignment = max(alignment,  (phys_addr_t)PAGE_SIZE <<
-                         max_t(unsigned long, MAX_ORDER - 1, pageblock_order));
+       /* Sanitise input arguments. */
+       alignment = max_t(phys_addr_t, alignment, CMA_MIN_ALIGNMENT_BYTES);
        if (fixed && base & (alignment - 1)) {
                ret = -EINVAL;
                pr_err("Region at %pa must be aligned to %pa bytes\n",