背景
说明:
1. 概述
此外, 2. 数据结构内核定义了 struct cma { unsigned long base_pfn; unsigned long count; unsigned long *bitmap; unsigned int order_per_bit; /* Order of pages represented by one bit */ struct mutex lock; #ifdef CONFIG_CMA_DEBUGFS struct hlist_head mem_head; spinlock_t mem_head_lock; #endif const char *name; }; extern struct cma cma_areas[MAX_CMA_AREAS]; extern unsigned cma_area_count;
来一张图就会清晰明了: 3. 流程分析3.1 CMA区域创建3.1.1 方式一 根据dts来配置之前的文章也都分析过,物理内存的描述放置在
在 RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup); 3.1.2 方式二 根据参数或宏配置可以通过内核参数或配置宏,来进行CMA区域的创建,最终会调用到 3.2 CMA添加到Buddy System在创建完 core_initcall(cma_init_reserved_areas);
3.3 CMA分配/释放
/** * cma_release() - release allocated pages * @cma: Contiguous memory region for which the allocation is performed. * @pages: Allocated pages. * @count: Number of allocated pages. * * This function releases memory allocated by alloc_cma(). * It returns false when provided pages do not belong to contiguous area and * true otherwise. */ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count) { unsigned long pfn; if (!cma || !pages) return false; pr_debug("%s(page %p)\n", __func__, (void *)pages); pfn = page_to_pfn(pages); if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) return false; VM_BUG_ON(pfn + count > cma->base_pfn + cma->count); free_contig_range(pfn, count); cma_clear_bitmap(cma, pfn, count); trace_cma_release(pfn, pages, count); return true; } 3.4 DMA使用代码参考 /** * dma_alloc_from_contiguous() - allocate pages from contiguous area * @dev: Pointer to device for which the allocation is performed. * @count: Requested number of pages. * @align: Requested alignment of pages (in PAGE_SIZE order). * @gfp_mask: GFP flags to use for this allocation. * * This function allocates memory buffer for specified device. It uses * device specific contiguous memory area if available or the default * global one. Requires architecture specific dev_get_cma_area() helper * function. */ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, unsigned int align, gfp_t gfp_mask); /** * dma_release_from_contiguous() - release allocated pages * @dev: Pointer to device for which the pages were allocated. * @pages: Allocated pages. * @count: Number of allocated pages. * * This function releases memory allocated by dma_alloc_from_contiguous(). * It returns false when provided pages do not belong to contiguous area and * true otherwise. */ bool dma_release_from_contiguous(struct device *dev, struct page *pages, int count); 在上述的接口中,实际调用的就是 整体来看,CMA分配器还是比较简单易懂,也不再深入分析。 4.后记内存管理的分析先告一段落,后续可能还会针对某些模块进一步的研究与完善。 接下来将研究 |
|