The flag GFP_DMA32 only effect in kmalloc_large currently. This patch will create caches with GFP_DMA32 to support kmalloc with size under KMALLOC_MAX_CACHE_SIZE. Signed-off-by: Jianqun Xu <jay.xu@xxxxxxxxxxxxxx> --- include/linux/slab.h | 7 +++++++ mm/slab_common.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/linux/slab.h b/include/linux/slab.h index be4ba5867ac5..f4317663d148 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -307,6 +307,9 @@ enum kmalloc_cache_type { KMALLOC_RECLAIM, #ifdef CONFIG_ZONE_DMA KMALLOC_DMA, +#endif +#ifdef CONFIG_ZONE_DMA32 + KMALLOC_DMA32, #endif NR_KMALLOC_TYPES }; @@ -331,6 +334,10 @@ static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags) */ return flags & __GFP_DMA ? KMALLOC_DMA : KMALLOC_RECLAIM; #else +#ifdef CONFIG_ZONE_DMA32 + if (unlikely(flags & __GFP_DMA32)) + return KMALLOC_DMA32; +#endif return flags & __GFP_RECLAIMABLE ? KMALLOC_RECLAIM : KMALLOC_NORMAL; #endif } diff --git a/mm/slab_common.c b/mm/slab_common.c index e981c80d216c..2a04736fe8f5 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -805,6 +805,20 @@ void __init create_kmalloc_caches(slab_flags_t flags) } } #endif +#ifdef CONFIG_ZONE_DMA32 + for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) { + struct kmem_cache *s = kmalloc_caches[KMALLOC_NORMAL][i]; + + if (s) { + unsigned int size = kmalloc_size(i); + const char *n = kmalloc_cache_name("dma32-kmalloc", size); + + BUG_ON(!n); + kmalloc_caches[KMALLOC_DMA32][i] = create_kmalloc_cache( + n, size, SLAB_CACHE_DMA32 | flags, 0, 0); + } + } +#endif } #endif /* !CONFIG_SLOB */ -- 2.25.1