/* Cannot allocate larger than MAX_PAGE_ORDER */
order = min(get_order(pool_size), MAX_PAGE_ORDER);
do {
pool_size = 1 << (PAGE_SHIFT + order); if (cma_in_zone(gfp))
page = dma_alloc_from_contiguous(NULL, 1 << order,
order, false); if (!page)
page = alloc_pages(gfp, order);
} while (!page && order-- > 0); if (!page) goto out;
arch_dma_prep_coherent(page, pool_size);
#ifdef CONFIG_DMA_DIRECT_REMAP
addr = dma_common_contiguous_remap(page, pool_size,
pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
__builtin_return_address(0)); if (!addr) goto free_page; #else
addr = page_to_virt(page); #endif /* * Memory in the atomic DMA pools must be unencrypted, the pools do not * shrink so no re-encryption occurs in dma_direct_free().
*/
ret = set_memory_decrypted((unsignedlong)page_to_virt(page),
1 << order); if (ret) goto remove_mapping;
ret = gen_pool_add_virt(pool, (unsignedlong)addr, page_to_phys(page),
pool_size, NUMA_NO_NODE); if (ret) goto encrypt_mapping;
ret = atomic_pool_expand(pool, pool_size, gfp); if (ret) {
gen_pool_destroy(pool);
pr_err("DMA: failed to allocate %zu KiB %pGg pool for atomic allocation\n",
pool_size >> 10, &gfp); return NULL;
}
pr_info("DMA: preallocated %zu KiB %pGg pool for atomic allocations\n",
gen_pool_size(pool) >> 10, &gfp); return pool;
}
staticint __init dma_atomic_pool_init(void)
{ int ret = 0;
/* * If coherent_pool was not used on the command line, default the pool * sizes to 128KB per 1GB of memory, min 128KB, max MAX_PAGE_ORDER.
*/ if (!atomic_pool_size) { unsignedlong pages = totalram_pages() / (SZ_1G / SZ_128K);
pages = min_t(unsignedlong, pages, MAX_ORDER_NR_PAGES);
atomic_pool_size = max_t(size_t, pages << PAGE_SHIFT, SZ_128K);
}
INIT_WORK(&atomic_pool_work, atomic_pool_work_fn);
atomic_pool_kernel = __dma_atomic_pool_init(atomic_pool_size,
GFP_KERNEL); if (!atomic_pool_kernel)
ret = -ENOMEM; if (has_managed_dma()) {
atomic_pool_dma = __dma_atomic_pool_init(atomic_pool_size,
GFP_KERNEL | GFP_DMA); if (!atomic_pool_dma)
ret = -ENOMEM;
} if (IS_ENABLED(CONFIG_ZONE_DMA32)) {
atomic_pool_dma32 = __dma_atomic_pool_init(atomic_pool_size,
GFP_KERNEL | GFP_DMA32); if (!atomic_pool_dma32)
ret = -ENOMEM;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.