Messages in this thread Patch in this message | | | From | Christoph Hellwig <> | Subject | [PATCH 3/3] dma-pool: limit DMA and DMA32 zone size pools | Date | Mon, 22 Aug 2022 08:12:55 +0200 |
| |
Limit the sizing of the atomic pools for allocations from ZONE_DMA and ZONE_DMA32 based on the number of pages actually present in those zones instead of the total memory.
Fixes: c84dc6e68a1d ("dma-pool: add additional coherent pools to map to gfp mask") Reported-by: Michal Hocko <mhocko@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Michal Hocko <mhocko@suse.com> --- kernel/dma/pool.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index 4b4c59d05e436..2a6c71311a175 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -192,28 +192,40 @@ static size_t calculate_pool_size(unsigned long zone_pages) return max_t(size_t, pages << PAGE_SHIFT, SZ_128K); } +static struct gen_pool * __init __maybe_unused zone_pool_init(int zone_idx, + gfp_t gfp) +{ + struct pglist_data *pgdat; + unsigned long nr_pages = 0; + + for_each_online_pgdat(pgdat) + nr_pages += zone_managed_pages(&pgdat->node_zones[zone_idx]); + + if (!nr_pages) + return NULL; + + return __dma_atomic_pool_init(calculate_pool_size(nr_pages), gfp); +} + static int __init dma_atomic_pool_init(void) { +#ifdef CONFIG_ZONE_DMA + atomic_pool_dma = zone_pool_init(ZONE_DMA, GFP_DMA); +#endif +#ifdef CONFIG_ZONE_DMA32 + atomic_pool_dma32 = zone_pool_init(ZONE_DMA32, GFP_DMA32); +#endif + /* * If coherent_pool was not used on the command line, default the pool * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER-1. */ if (!atomic_pool_size) atomic_pool_size = calculate_pool_size(totalram_pages()); - - INIT_WORK(&atomic_pool_work, atomic_pool_work_fn); - atomic_pool_kernel = __dma_atomic_pool_init(atomic_pool_size, GFP_KERNEL); - if (has_managed_dma()) { - atomic_pool_dma = __dma_atomic_pool_init(atomic_pool_size, - GFP_KERNEL | GFP_DMA); - } - if (IS_ENABLED(CONFIG_ZONE_DMA32)) { - atomic_pool_dma32 = __dma_atomic_pool_init(atomic_pool_size, - GFP_KERNEL | GFP_DMA32); - } + INIT_WORK(&atomic_pool_work, atomic_pool_work_fn); dma_atomic_pool_debugfs_init(); return 0; } -- 2.30.2
| |