*参照元 [#k36c4542] #backlinks *説明 [#x060ae1a] -パス: [[linux-4.4.1/mm/cma.c]] -FIXME: これは何? --説明 **引数 [#m2ca9094] -struct cma *cma -- --[[linux-4.4.1/cma]] -size_t count -- -unsigned int align -- **返り値 [#k5d5a970] -struct page * -- --[[linux-4.4.1/page]] **参考 [#te23a298] *実装 [#h0e93adc] /** * cma_alloc() - allocate pages from contiguous area * @cma: Contiguous memory region for which the allocation is performed. * @count: Requested number of pages. * @align: Requested alignment of pages (in PAGE_SIZE order). * * This function allocates part of contiguous memory on specific * contiguous memory area. */ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) { unsigned long mask, offset; unsigned long pfn = -1; unsigned long start = 0; unsigned long bitmap_maxno, bitmap_no, bitmap_count; struct page *page = NULL; int ret; if (!cma || !cma->count) return NULL; pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma, count, align); - --[[linux-4.4.1/pr_debug()]] if (!count) return NULL; mask = cma_bitmap_aligned_mask(cma, align); offset = cma_bitmap_aligned_offset(cma, align); bitmap_maxno = cma_bitmap_maxno(cma); bitmap_count = cma_bitmap_pages_to_bits(cma, count); - --[[linux-4.4.1/cma_bitmap_aligned_mask()]] --[[linux-4.4.1/cma_bitmap_aligned_offset()]] --[[linux-4.4.1/cma_bitmap_maxno()]] --[[linux-4.4.1/cma_bitmap_pages_to_bits()]] for (;;) { mutex_lock(&cma->lock); bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap, bitmap_maxno, start, bitmap_count, mask, offset); - --[[linux-4.4.1/mutex_lock()]] --[[linux-4.4.1/bitmap_find_next_zero_area_off()]] if (bitmap_no >= bitmap_maxno) { mutex_unlock(&cma->lock); break; } bitmap_set(cma->bitmap, bitmap_no, bitmap_count); - --[[linux-4.4.1/mutex_unlock()]] --[[linux-4.4.1/bitmap_set()]] /* * It's safe to drop the lock here. We've marked this region for * our exclusive use. If the migration fails we will take the * lock again and unmark it. */ mutex_unlock(&cma->lock); pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); mutex_lock(&cma_mutex); ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA); mutex_unlock(&cma_mutex); - --[[linux-4.4.1/alloc_contig_range()]] --[[linux-4.4.1/MIGRATE_CMA]] if (ret == 0) { page = pfn_to_page(pfn); break; } - --[[linux-4.4.1/pfn_to_page()]] cma_clear_bitmap(cma, pfn, count); if (ret != -EBUSY) break; - --[[linux-4.4.1/cma_clear_bitmap()]] pr_debug("%s(): memory range at %p is busy, retrying\n", __func__, pfn_to_page(pfn)); /* try again with a bit different memory target */ start = bitmap_no + mask + 1; } trace_cma_alloc(pfn, page, count, align); - --[[linux-4.4.1/trace_cma_alloc()]] pr_debug("%s(): returned %p\n", __func__, page); return page; } *コメント [#o7fb96ad]