On Thu 11-08-22 11:29:11, Christoph Hellwig wrote: > This is what I think should solve your problem properly: > > http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-pool-sizing http://git.infradead.org/users/hch/misc.git/commit/a29d77929bf4fc563657b29da1506a12ad0f4610 +unsigned long __init nr_pages_per_zone(int zone_index) +{ + return arch_zone_highest_possible_pfn[zone_index] - + arch_zone_lowest_possible_pfn[zone_index]; +} + this will not consider any gaps in the zone. We have zone_managed_pages which tells you how many pages there are in the zone which have been provided to the page allocator which seems like something that would fit better. And it is also much better than basing it on the global amount of memory which just doesn't make much sens for constrained zones Except that it will not work for this case as +static unsigned long calculate_pool_size(unsigned long zone_pages) +{ + unsigned long nr_pages = min_t(unsigned long, + zone_pages / (SZ_1G / SZ_128K), + MAX_ORDER_NR_PAGES); + + return max_t(unsigned long, nr_pages << PAGE_SHIFT, SZ_128K); +} this will return 128kB, correct? + atomic_pool_dma = __dma_atomic_pool_init( + calculate_pool_size(nr_zone_dma_pages), + GFP_DMA); The DMA zone still has 126kB of usable memory. I think what you want/need to do something like pool_size = calculate_pool_size(nr_zone_dma_pages); do { atomic_pool_dma = __dma_atomic_pool_init(pool_size), GFP_DMA | __GFP_NOWARN); if (atomic_pool_dma) { break; pool_size /= 2; } while (pool_size > PAGE_SZIE); if (!atomic_pool_dma) print_something_useful; Another option would be to consider NR_FREE_PAGES of the zone but that would be inherently racy. -- Michal Hocko SUSE Labs