18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Contiguous Memory Allocator 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011 by Samsung Electronics. 68c2ecf20Sopenharmony_ci * Copyright IBM Corporation, 2013 78c2ecf20Sopenharmony_ci * Copyright LG Electronics Inc., 2014 88c2ecf20Sopenharmony_ci * Written by: 98c2ecf20Sopenharmony_ci * Marek Szyprowski <m.szyprowski@samsung.com> 108c2ecf20Sopenharmony_ci * Michal Nazarewicz <mina86@mina86.com> 118c2ecf20Sopenharmony_ci * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 128c2ecf20Sopenharmony_ci * Joonsoo Kim <iamjoonsoo.kim@lge.com> 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "cma: " fmt 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef CONFIG_CMA_DEBUG 188c2ecf20Sopenharmony_ci#ifndef DEBUG 198c2ecf20Sopenharmony_ci# define DEBUG 208c2ecf20Sopenharmony_ci#endif 218c2ecf20Sopenharmony_ci#endif 228c2ecf20Sopenharmony_ci#define CREATE_TRACE_POINTS 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include <linux/memblock.h> 258c2ecf20Sopenharmony_ci#include <linux/err.h> 268c2ecf20Sopenharmony_ci#include <linux/mm.h> 278c2ecf20Sopenharmony_ci#include <linux/mutex.h> 288c2ecf20Sopenharmony_ci#include <linux/sizes.h> 298c2ecf20Sopenharmony_ci#include <linux/slab.h> 308c2ecf20Sopenharmony_ci#include <linux/log2.h> 318c2ecf20Sopenharmony_ci#include <linux/cma.h> 328c2ecf20Sopenharmony_ci#include <linux/highmem.h> 338c2ecf20Sopenharmony_ci#include <linux/io.h> 348c2ecf20Sopenharmony_ci#include <linux/kmemleak.h> 358c2ecf20Sopenharmony_ci#include <trace/events/cma.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "cma.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistruct cma cma_areas[MAX_CMA_AREAS]; 408c2ecf20Sopenharmony_ciunsigned cma_area_count; 418c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(cma_mutex); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciphys_addr_t cma_get_base(const struct cma *cma) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci return PFN_PHYS(cma->base_pfn); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciunsigned long cma_get_size(const struct cma *cma) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci return cma->count << PAGE_SHIFT; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciconst char *cma_get_name(const struct cma *cma) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci return cma->name; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic unsigned long cma_bitmap_aligned_mask(const struct cma *cma, 598c2ecf20Sopenharmony_ci unsigned int align_order) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci if (align_order <= cma->order_per_bit) 628c2ecf20Sopenharmony_ci return 0; 638c2ecf20Sopenharmony_ci return (1UL << (align_order - cma->order_per_bit)) - 1; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* 678c2ecf20Sopenharmony_ci * Find the offset of the base PFN from the specified align_order. 688c2ecf20Sopenharmony_ci * The value returned is represented in order_per_bits. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistatic unsigned long cma_bitmap_aligned_offset(const struct cma *cma, 718c2ecf20Sopenharmony_ci unsigned int align_order) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci return (cma->base_pfn & ((1UL << align_order) - 1)) 748c2ecf20Sopenharmony_ci >> cma->order_per_bit; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic unsigned long cma_bitmap_pages_to_bits(const struct cma *cma, 788c2ecf20Sopenharmony_ci unsigned long pages) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci return ALIGN(pages, 1UL << cma->order_per_bit) >> cma->order_per_bit; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic void cma_clear_bitmap(struct cma *cma, unsigned long pfn, 848c2ecf20Sopenharmony_ci unsigned int count) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci unsigned long bitmap_no, bitmap_count; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci bitmap_no = (pfn - cma->base_pfn) >> cma->order_per_bit; 898c2ecf20Sopenharmony_ci bitmap_count = cma_bitmap_pages_to_bits(cma, count); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci mutex_lock(&cma->lock); 928c2ecf20Sopenharmony_ci bitmap_clear(cma->bitmap, bitmap_no, bitmap_count); 938c2ecf20Sopenharmony_ci mutex_unlock(&cma->lock); 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic void __init cma_activate_area(struct cma *cma) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; 998c2ecf20Sopenharmony_ci unsigned i = cma->count >> pageblock_order; 1008c2ecf20Sopenharmony_ci struct zone *zone; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci cma->bitmap = bitmap_zalloc(cma_bitmap_maxno(cma), GFP_KERNEL); 1038c2ecf20Sopenharmony_ci if (!cma->bitmap) 1048c2ecf20Sopenharmony_ci goto out_error; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci WARN_ON_ONCE(!pfn_valid(pfn)); 1078c2ecf20Sopenharmony_ci zone = page_zone(pfn_to_page(pfn)); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci do { 1108c2ecf20Sopenharmony_ci unsigned j; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci base_pfn = pfn; 1138c2ecf20Sopenharmony_ci for (j = pageblock_nr_pages; j; --j, pfn++) { 1148c2ecf20Sopenharmony_ci WARN_ON_ONCE(!pfn_valid(pfn)); 1158c2ecf20Sopenharmony_ci /* 1168c2ecf20Sopenharmony_ci * alloc_contig_range requires the pfn range 1178c2ecf20Sopenharmony_ci * specified to be in the same zone. Make this 1188c2ecf20Sopenharmony_ci * simple by forcing the entire CMA resv range 1198c2ecf20Sopenharmony_ci * to be in the same zone. 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_ci if (page_zone(pfn_to_page(pfn)) != zone) 1228c2ecf20Sopenharmony_ci goto not_in_zone; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci init_cma_reserved_pageblock(pfn_to_page(base_pfn)); 1258c2ecf20Sopenharmony_ci } while (--i); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci mutex_init(&cma->lock); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci#ifdef CONFIG_CMA_DEBUGFS 1308c2ecf20Sopenharmony_ci INIT_HLIST_HEAD(&cma->mem_head); 1318c2ecf20Sopenharmony_ci spin_lock_init(&cma->mem_head_lock); 1328c2ecf20Sopenharmony_ci#endif 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci return; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cinot_in_zone: 1378c2ecf20Sopenharmony_ci bitmap_free(cma->bitmap); 1388c2ecf20Sopenharmony_ciout_error: 1398c2ecf20Sopenharmony_ci cma->count = 0; 1408c2ecf20Sopenharmony_ci pr_err("CMA area %s could not be activated\n", cma->name); 1418c2ecf20Sopenharmony_ci return; 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic int __init cma_init_reserved_areas(void) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci int i; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci for (i = 0; i < cma_area_count; i++) 1498c2ecf20Sopenharmony_ci cma_activate_area(&cma_areas[i]); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci return 0; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_cicore_initcall(cma_init_reserved_areas); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/** 1568c2ecf20Sopenharmony_ci * cma_init_reserved_mem() - create custom contiguous area from reserved memory 1578c2ecf20Sopenharmony_ci * @base: Base address of the reserved area 1588c2ecf20Sopenharmony_ci * @size: Size of the reserved area (in bytes), 1598c2ecf20Sopenharmony_ci * @order_per_bit: Order of pages represented by one bit on bitmap. 1608c2ecf20Sopenharmony_ci * @name: The name of the area. If this parameter is NULL, the name of 1618c2ecf20Sopenharmony_ci * the area will be set to "cmaN", where N is a running counter of 1628c2ecf20Sopenharmony_ci * used areas. 1638c2ecf20Sopenharmony_ci * @res_cma: Pointer to store the created cma region. 1648c2ecf20Sopenharmony_ci * 1658c2ecf20Sopenharmony_ci * This function creates custom contiguous area from already reserved memory. 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_ciint __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, 1688c2ecf20Sopenharmony_ci unsigned int order_per_bit, 1698c2ecf20Sopenharmony_ci const char *name, 1708c2ecf20Sopenharmony_ci struct cma **res_cma) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci struct cma *cma; 1738c2ecf20Sopenharmony_ci phys_addr_t alignment; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* Sanity checks */ 1768c2ecf20Sopenharmony_ci if (cma_area_count == ARRAY_SIZE(cma_areas)) { 1778c2ecf20Sopenharmony_ci pr_err("Not enough slots for CMA reserved regions!\n"); 1788c2ecf20Sopenharmony_ci return -ENOSPC; 1798c2ecf20Sopenharmony_ci } 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci if (!size || !memblock_is_region_reserved(base, size)) 1828c2ecf20Sopenharmony_ci return -EINVAL; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci /* ensure minimal alignment required by mm core */ 1858c2ecf20Sopenharmony_ci alignment = PAGE_SIZE << 1868c2ecf20Sopenharmony_ci max_t(unsigned long, MAX_ORDER - 1, pageblock_order); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci /* alignment should be aligned with order_per_bit */ 1898c2ecf20Sopenharmony_ci if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit)) 1908c2ecf20Sopenharmony_ci return -EINVAL; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size) 1938c2ecf20Sopenharmony_ci return -EINVAL; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci /* 1968c2ecf20Sopenharmony_ci * Each reserved area must be initialised later, when more kernel 1978c2ecf20Sopenharmony_ci * subsystems (like slab allocator) are available. 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci cma = &cma_areas[cma_area_count]; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci if (name) 2028c2ecf20Sopenharmony_ci snprintf(cma->name, CMA_MAX_NAME, name); 2038c2ecf20Sopenharmony_ci else 2048c2ecf20Sopenharmony_ci snprintf(cma->name, CMA_MAX_NAME, "cma%d\n", cma_area_count); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci cma->base_pfn = PFN_DOWN(base); 2078c2ecf20Sopenharmony_ci cma->count = size >> PAGE_SHIFT; 2088c2ecf20Sopenharmony_ci cma->order_per_bit = order_per_bit; 2098c2ecf20Sopenharmony_ci *res_cma = cma; 2108c2ecf20Sopenharmony_ci cma_area_count++; 2118c2ecf20Sopenharmony_ci totalcma_pages += (size / PAGE_SIZE); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci return 0; 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci/** 2178c2ecf20Sopenharmony_ci * cma_declare_contiguous_nid() - reserve custom contiguous area 2188c2ecf20Sopenharmony_ci * @base: Base address of the reserved area optional, use 0 for any 2198c2ecf20Sopenharmony_ci * @size: Size of the reserved area (in bytes), 2208c2ecf20Sopenharmony_ci * @limit: End address of the reserved memory (optional, 0 for any). 2218c2ecf20Sopenharmony_ci * @alignment: Alignment for the CMA area, should be power of 2 or zero 2228c2ecf20Sopenharmony_ci * @order_per_bit: Order of pages represented by one bit on bitmap. 2238c2ecf20Sopenharmony_ci * @fixed: hint about where to place the reserved area 2248c2ecf20Sopenharmony_ci * @name: The name of the area. See function cma_init_reserved_mem() 2258c2ecf20Sopenharmony_ci * @res_cma: Pointer to store the created cma region. 2268c2ecf20Sopenharmony_ci * @nid: nid of the free area to find, %NUMA_NO_NODE for any node 2278c2ecf20Sopenharmony_ci * 2288c2ecf20Sopenharmony_ci * This function reserves memory from early allocator. It should be 2298c2ecf20Sopenharmony_ci * called by arch specific code once the early allocator (memblock or bootmem) 2308c2ecf20Sopenharmony_ci * has been activated and all other subsystems have already allocated/reserved 2318c2ecf20Sopenharmony_ci * memory. This function allows to create custom reserved areas. 2328c2ecf20Sopenharmony_ci * 2338c2ecf20Sopenharmony_ci * If @fixed is true, reserve contiguous area at exactly @base. If false, 2348c2ecf20Sopenharmony_ci * reserve in range from @base to @limit. 2358c2ecf20Sopenharmony_ci */ 2368c2ecf20Sopenharmony_ciint __init cma_declare_contiguous_nid(phys_addr_t base, 2378c2ecf20Sopenharmony_ci phys_addr_t size, phys_addr_t limit, 2388c2ecf20Sopenharmony_ci phys_addr_t alignment, unsigned int order_per_bit, 2398c2ecf20Sopenharmony_ci bool fixed, const char *name, struct cma **res_cma, 2408c2ecf20Sopenharmony_ci int nid) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci phys_addr_t memblock_end = memblock_end_of_DRAM(); 2438c2ecf20Sopenharmony_ci phys_addr_t highmem_start; 2448c2ecf20Sopenharmony_ci int ret = 0; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci /* 2478c2ecf20Sopenharmony_ci * We can't use __pa(high_memory) directly, since high_memory 2488c2ecf20Sopenharmony_ci * isn't a valid direct map VA, and DEBUG_VIRTUAL will (validly) 2498c2ecf20Sopenharmony_ci * complain. Find the boundary by adding one to the last valid 2508c2ecf20Sopenharmony_ci * address. 2518c2ecf20Sopenharmony_ci */ 2528c2ecf20Sopenharmony_ci highmem_start = __pa(high_memory - 1) + 1; 2538c2ecf20Sopenharmony_ci pr_debug("%s(size %pa, base %pa, limit %pa alignment %pa)\n", 2548c2ecf20Sopenharmony_ci __func__, &size, &base, &limit, &alignment); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (cma_area_count == ARRAY_SIZE(cma_areas)) { 2578c2ecf20Sopenharmony_ci pr_err("Not enough slots for CMA reserved regions!\n"); 2588c2ecf20Sopenharmony_ci return -ENOSPC; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci if (!size) 2628c2ecf20Sopenharmony_ci return -EINVAL; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci if (alignment && !is_power_of_2(alignment)) 2658c2ecf20Sopenharmony_ci return -EINVAL; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci /* 2688c2ecf20Sopenharmony_ci * Sanitise input arguments. 2698c2ecf20Sopenharmony_ci * Pages both ends in CMA area could be merged into adjacent unmovable 2708c2ecf20Sopenharmony_ci * migratetype page by page allocator's buddy algorithm. In the case, 2718c2ecf20Sopenharmony_ci * you couldn't get a contiguous memory, which is not what we want. 2728c2ecf20Sopenharmony_ci */ 2738c2ecf20Sopenharmony_ci alignment = max(alignment, (phys_addr_t)PAGE_SIZE << 2748c2ecf20Sopenharmony_ci max_t(unsigned long, MAX_ORDER - 1, pageblock_order)); 2758c2ecf20Sopenharmony_ci if (fixed && base & (alignment - 1)) { 2768c2ecf20Sopenharmony_ci ret = -EINVAL; 2778c2ecf20Sopenharmony_ci pr_err("Region at %pa must be aligned to %pa bytes\n", 2788c2ecf20Sopenharmony_ci &base, &alignment); 2798c2ecf20Sopenharmony_ci goto err; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci base = ALIGN(base, alignment); 2828c2ecf20Sopenharmony_ci size = ALIGN(size, alignment); 2838c2ecf20Sopenharmony_ci limit &= ~(alignment - 1); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci if (!base) 2868c2ecf20Sopenharmony_ci fixed = false; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* size should be aligned with order_per_bit */ 2898c2ecf20Sopenharmony_ci if (!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)) 2908c2ecf20Sopenharmony_ci return -EINVAL; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci /* 2938c2ecf20Sopenharmony_ci * If allocating at a fixed base the request region must not cross the 2948c2ecf20Sopenharmony_ci * low/high memory boundary. 2958c2ecf20Sopenharmony_ci */ 2968c2ecf20Sopenharmony_ci if (fixed && base < highmem_start && base + size > highmem_start) { 2978c2ecf20Sopenharmony_ci ret = -EINVAL; 2988c2ecf20Sopenharmony_ci pr_err("Region at %pa defined on low/high memory boundary (%pa)\n", 2998c2ecf20Sopenharmony_ci &base, &highmem_start); 3008c2ecf20Sopenharmony_ci goto err; 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* 3048c2ecf20Sopenharmony_ci * If the limit is unspecified or above the memblock end, its effective 3058c2ecf20Sopenharmony_ci * value will be the memblock end. Set it explicitly to simplify further 3068c2ecf20Sopenharmony_ci * checks. 3078c2ecf20Sopenharmony_ci */ 3088c2ecf20Sopenharmony_ci if (limit == 0 || limit > memblock_end) 3098c2ecf20Sopenharmony_ci limit = memblock_end; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (base + size > limit) { 3128c2ecf20Sopenharmony_ci ret = -EINVAL; 3138c2ecf20Sopenharmony_ci pr_err("Size (%pa) of region at %pa exceeds limit (%pa)\n", 3148c2ecf20Sopenharmony_ci &size, &base, &limit); 3158c2ecf20Sopenharmony_ci goto err; 3168c2ecf20Sopenharmony_ci } 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci /* Reserve memory */ 3198c2ecf20Sopenharmony_ci if (fixed) { 3208c2ecf20Sopenharmony_ci if (memblock_is_region_reserved(base, size) || 3218c2ecf20Sopenharmony_ci memblock_reserve(base, size) < 0) { 3228c2ecf20Sopenharmony_ci ret = -EBUSY; 3238c2ecf20Sopenharmony_ci goto err; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci } else { 3268c2ecf20Sopenharmony_ci phys_addr_t addr = 0; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci /* 3298c2ecf20Sopenharmony_ci * All pages in the reserved area must come from the same zone. 3308c2ecf20Sopenharmony_ci * If the requested region crosses the low/high memory boundary, 3318c2ecf20Sopenharmony_ci * try allocating from high memory first and fall back to low 3328c2ecf20Sopenharmony_ci * memory in case of failure. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_ci if (base < highmem_start && limit > highmem_start) { 3358c2ecf20Sopenharmony_ci addr = memblock_alloc_range_nid(size, alignment, 3368c2ecf20Sopenharmony_ci highmem_start, limit, nid, true); 3378c2ecf20Sopenharmony_ci limit = highmem_start; 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci if (!addr) { 3418c2ecf20Sopenharmony_ci addr = memblock_alloc_range_nid(size, alignment, base, 3428c2ecf20Sopenharmony_ci limit, nid, true); 3438c2ecf20Sopenharmony_ci if (!addr) { 3448c2ecf20Sopenharmony_ci ret = -ENOMEM; 3458c2ecf20Sopenharmony_ci goto err; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci /* 3508c2ecf20Sopenharmony_ci * kmemleak scans/reads tracked objects for pointers to other 3518c2ecf20Sopenharmony_ci * objects but this address isn't mapped and accessible 3528c2ecf20Sopenharmony_ci */ 3538c2ecf20Sopenharmony_ci kmemleak_ignore_phys(addr); 3548c2ecf20Sopenharmony_ci base = addr; 3558c2ecf20Sopenharmony_ci } 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci ret = cma_init_reserved_mem(base, size, order_per_bit, name, res_cma); 3588c2ecf20Sopenharmony_ci if (ret) 3598c2ecf20Sopenharmony_ci goto free_mem; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci pr_info("Reserved %ld MiB at %pa\n", (unsigned long)size / SZ_1M, 3628c2ecf20Sopenharmony_ci &base); 3638c2ecf20Sopenharmony_ci return 0; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cifree_mem: 3668c2ecf20Sopenharmony_ci memblock_free(base, size); 3678c2ecf20Sopenharmony_cierr: 3688c2ecf20Sopenharmony_ci pr_err("Failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); 3698c2ecf20Sopenharmony_ci return ret; 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci#ifdef CONFIG_CMA_DEBUG 3738c2ecf20Sopenharmony_cistatic void cma_debug_show_areas(struct cma *cma) 3748c2ecf20Sopenharmony_ci{ 3758c2ecf20Sopenharmony_ci unsigned long next_zero_bit, next_set_bit, nr_zero; 3768c2ecf20Sopenharmony_ci unsigned long start = 0; 3778c2ecf20Sopenharmony_ci unsigned long nr_part, nr_total = 0; 3788c2ecf20Sopenharmony_ci unsigned long nbits = cma_bitmap_maxno(cma); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci mutex_lock(&cma->lock); 3818c2ecf20Sopenharmony_ci pr_info("number of available pages: "); 3828c2ecf20Sopenharmony_ci for (;;) { 3838c2ecf20Sopenharmony_ci next_zero_bit = find_next_zero_bit(cma->bitmap, nbits, start); 3848c2ecf20Sopenharmony_ci if (next_zero_bit >= nbits) 3858c2ecf20Sopenharmony_ci break; 3868c2ecf20Sopenharmony_ci next_set_bit = find_next_bit(cma->bitmap, nbits, next_zero_bit); 3878c2ecf20Sopenharmony_ci nr_zero = next_set_bit - next_zero_bit; 3888c2ecf20Sopenharmony_ci nr_part = nr_zero << cma->order_per_bit; 3898c2ecf20Sopenharmony_ci pr_cont("%s%lu@%lu", nr_total ? "+" : "", nr_part, 3908c2ecf20Sopenharmony_ci next_zero_bit); 3918c2ecf20Sopenharmony_ci nr_total += nr_part; 3928c2ecf20Sopenharmony_ci start = next_zero_bit + nr_zero; 3938c2ecf20Sopenharmony_ci } 3948c2ecf20Sopenharmony_ci pr_cont("=> %lu free of %lu total pages\n", nr_total, cma->count); 3958c2ecf20Sopenharmony_ci mutex_unlock(&cma->lock); 3968c2ecf20Sopenharmony_ci} 3978c2ecf20Sopenharmony_ci#else 3988c2ecf20Sopenharmony_cistatic inline void cma_debug_show_areas(struct cma *cma) { } 3998c2ecf20Sopenharmony_ci#endif 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci/** 4028c2ecf20Sopenharmony_ci * cma_alloc() - allocate pages from contiguous area 4038c2ecf20Sopenharmony_ci * @cma: Contiguous memory region for which the allocation is performed. 4048c2ecf20Sopenharmony_ci * @count: Requested number of pages. 4058c2ecf20Sopenharmony_ci * @align: Requested alignment of pages (in PAGE_SIZE order). 4068c2ecf20Sopenharmony_ci * @no_warn: Avoid printing message about failed allocation 4078c2ecf20Sopenharmony_ci * 4088c2ecf20Sopenharmony_ci * This function allocates part of contiguous memory on specific 4098c2ecf20Sopenharmony_ci * contiguous memory area. 4108c2ecf20Sopenharmony_ci */ 4118c2ecf20Sopenharmony_cistruct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, 4128c2ecf20Sopenharmony_ci bool no_warn) 4138c2ecf20Sopenharmony_ci{ 4148c2ecf20Sopenharmony_ci unsigned long mask, offset; 4158c2ecf20Sopenharmony_ci unsigned long pfn = -1; 4168c2ecf20Sopenharmony_ci unsigned long start = 0; 4178c2ecf20Sopenharmony_ci unsigned long bitmap_maxno, bitmap_no, bitmap_count; 4188c2ecf20Sopenharmony_ci size_t i; 4198c2ecf20Sopenharmony_ci struct page *page = NULL; 4208c2ecf20Sopenharmony_ci int ret = -ENOMEM; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci if (!cma || !cma->count || !cma->bitmap) 4238c2ecf20Sopenharmony_ci return NULL; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma, 4268c2ecf20Sopenharmony_ci count, align); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci if (!count) 4298c2ecf20Sopenharmony_ci return NULL; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci mask = cma_bitmap_aligned_mask(cma, align); 4328c2ecf20Sopenharmony_ci offset = cma_bitmap_aligned_offset(cma, align); 4338c2ecf20Sopenharmony_ci bitmap_maxno = cma_bitmap_maxno(cma); 4348c2ecf20Sopenharmony_ci bitmap_count = cma_bitmap_pages_to_bits(cma, count); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci if (bitmap_count > bitmap_maxno) 4378c2ecf20Sopenharmony_ci return NULL; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci for (;;) { 4408c2ecf20Sopenharmony_ci mutex_lock(&cma->lock); 4418c2ecf20Sopenharmony_ci bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap, 4428c2ecf20Sopenharmony_ci bitmap_maxno, start, bitmap_count, mask, 4438c2ecf20Sopenharmony_ci offset); 4448c2ecf20Sopenharmony_ci if (bitmap_no >= bitmap_maxno) { 4458c2ecf20Sopenharmony_ci mutex_unlock(&cma->lock); 4468c2ecf20Sopenharmony_ci break; 4478c2ecf20Sopenharmony_ci } 4488c2ecf20Sopenharmony_ci bitmap_set(cma->bitmap, bitmap_no, bitmap_count); 4498c2ecf20Sopenharmony_ci /* 4508c2ecf20Sopenharmony_ci * It's safe to drop the lock here. We've marked this region for 4518c2ecf20Sopenharmony_ci * our exclusive use. If the migration fails we will take the 4528c2ecf20Sopenharmony_ci * lock again and unmark it. 4538c2ecf20Sopenharmony_ci */ 4548c2ecf20Sopenharmony_ci mutex_unlock(&cma->lock); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); 4578c2ecf20Sopenharmony_ci mutex_lock(&cma_mutex); 4588c2ecf20Sopenharmony_ci ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, 4598c2ecf20Sopenharmony_ci GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0)); 4608c2ecf20Sopenharmony_ci mutex_unlock(&cma_mutex); 4618c2ecf20Sopenharmony_ci if (ret == 0) { 4628c2ecf20Sopenharmony_ci page = pfn_to_page(pfn); 4638c2ecf20Sopenharmony_ci break; 4648c2ecf20Sopenharmony_ci } 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci cma_clear_bitmap(cma, pfn, count); 4678c2ecf20Sopenharmony_ci if (ret != -EBUSY) 4688c2ecf20Sopenharmony_ci break; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci pr_debug("%s(): memory range at %p is busy, retrying\n", 4718c2ecf20Sopenharmony_ci __func__, pfn_to_page(pfn)); 4728c2ecf20Sopenharmony_ci /* try again with a bit different memory target */ 4738c2ecf20Sopenharmony_ci start = bitmap_no + mask + 1; 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci trace_cma_alloc(pfn, page, count, align); 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* 4798c2ecf20Sopenharmony_ci * CMA can allocate multiple page blocks, which results in different 4808c2ecf20Sopenharmony_ci * blocks being marked with different tags. Reset the tags to ignore 4818c2ecf20Sopenharmony_ci * those page blocks. 4828c2ecf20Sopenharmony_ci */ 4838c2ecf20Sopenharmony_ci if (page) { 4848c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) 4858c2ecf20Sopenharmony_ci page_kasan_tag_reset(nth_page(page, i)); 4868c2ecf20Sopenharmony_ci } 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci if (ret && !no_warn) { 4898c2ecf20Sopenharmony_ci pr_err("%s: alloc failed, req-size: %zu pages, ret: %d\n", 4908c2ecf20Sopenharmony_ci __func__, count, ret); 4918c2ecf20Sopenharmony_ci cma_debug_show_areas(cma); 4928c2ecf20Sopenharmony_ci } 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci pr_debug("%s(): returned %p\n", __func__, page); 4958c2ecf20Sopenharmony_ci return page; 4968c2ecf20Sopenharmony_ci} 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci/** 4998c2ecf20Sopenharmony_ci * cma_release() - release allocated pages 5008c2ecf20Sopenharmony_ci * @cma: Contiguous memory region for which the allocation is performed. 5018c2ecf20Sopenharmony_ci * @pages: Allocated pages. 5028c2ecf20Sopenharmony_ci * @count: Number of allocated pages. 5038c2ecf20Sopenharmony_ci * 5048c2ecf20Sopenharmony_ci * This function releases memory allocated by cma_alloc(). 5058c2ecf20Sopenharmony_ci * It returns false when provided pages do not belong to contiguous area and 5068c2ecf20Sopenharmony_ci * true otherwise. 5078c2ecf20Sopenharmony_ci */ 5088c2ecf20Sopenharmony_cibool cma_release(struct cma *cma, const struct page *pages, unsigned int count) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci unsigned long pfn; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci if (!cma || !pages) 5138c2ecf20Sopenharmony_ci return false; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci pr_debug("%s(page %p)\n", __func__, (void *)pages); 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci pfn = page_to_pfn(pages); 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) 5208c2ecf20Sopenharmony_ci return false; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci VM_BUG_ON(pfn + count > cma->base_pfn + cma->count); 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci free_contig_range(pfn, count); 5258c2ecf20Sopenharmony_ci cma_clear_bitmap(cma, pfn, count); 5268c2ecf20Sopenharmony_ci trace_cma_release(pfn, pages, count); 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci return true; 5298c2ecf20Sopenharmony_ci} 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ciint cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) 5328c2ecf20Sopenharmony_ci{ 5338c2ecf20Sopenharmony_ci int i; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci for (i = 0; i < cma_area_count; i++) { 5368c2ecf20Sopenharmony_ci int ret = it(&cma_areas[i], data); 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci if (ret) 5398c2ecf20Sopenharmony_ci return ret; 5408c2ecf20Sopenharmony_ci } 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci return 0; 5438c2ecf20Sopenharmony_ci} 544