diff mbox series

[bpf,2/4] page_alloc: use vmalloc_huge for large system hash

Message ID 20220422051813.1989257-3-song@kernel.org (mailing list archive)
State New
Headers show
Series bpf_prog_pack and vmalloc-on-huge-page fixes | expand

Commit Message

Song Liu April 22, 2022, 5:18 a.m. UTC
Use vmalloc_huge() in alloc_large_system_hash() so that large system hash
(>= PMD_SIZE) could benefit from huge pages. Note that vmalloc_huge only
allocates huge pages for systems with HAVE_ARCH_HUGE_VMALLOC.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Song Liu <song@kernel.org>
---
 mm/page_alloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

kernel test robot April 22, 2022, 9:06 a.m. UTC | #1
Hi Song,

I love your patch! Yet something to improve:

[auto build test ERROR on bpf/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Song-Liu/bpf_prog_pack-and-vmalloc-on-huge-page-fixes/20220422-133605
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master
config: i386-randconfig-a001 (https://download.01.org/0day-ci/archive/20220422/202204221628.82Qczjsq-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/239fb9ca743cf33db8d56df7957726e19aea87d5
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Song-Liu/bpf_prog_pack-and-vmalloc-on-huge-page-fixes/20220422-133605
        git checkout 239fb9ca743cf33db8d56df7957726e19aea87d5
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   mm/page_alloc.c: In function 'alloc_large_system_hash':
>> mm/page_alloc.c:8921:33: error: implicit declaration of function 'vmalloc_huge'; did you mean 'vmalloc_no_huge'? [-Werror=implicit-function-declaration]
    8921 |                         table = vmalloc_huge(size, gfp_flags);
         |                                 ^~~~~~~~~~~~
         |                                 vmalloc_no_huge
>> mm/page_alloc.c:8921:31: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    8921 |                         table = vmalloc_huge(size, gfp_flags);
         |                               ^
   cc1: some warnings being treated as errors


vim +8921 mm/page_alloc.c

  8876	
  8877			/* limit to 1 bucket per 2^scale bytes of low memory */
  8878			if (scale > PAGE_SHIFT)
  8879				numentries >>= (scale - PAGE_SHIFT);
  8880			else
  8881				numentries <<= (PAGE_SHIFT - scale);
  8882	
  8883			/* Make sure we've got at least a 0-order allocation.. */
  8884			if (unlikely(flags & HASH_SMALL)) {
  8885				/* Makes no sense without HASH_EARLY */
  8886				WARN_ON(!(flags & HASH_EARLY));
  8887				if (!(numentries >> *_hash_shift)) {
  8888					numentries = 1UL << *_hash_shift;
  8889					BUG_ON(!numentries);
  8890				}
  8891			} else if (unlikely((numentries * bucketsize) < PAGE_SIZE))
  8892				numentries = PAGE_SIZE / bucketsize;
  8893		}
  8894		numentries = roundup_pow_of_two(numentries);
  8895	
  8896		/* limit allocation size to 1/16 total memory by default */
  8897		if (max == 0) {
  8898			max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
  8899			do_div(max, bucketsize);
  8900		}
  8901		max = min(max, 0x80000000ULL);
  8902	
  8903		if (numentries < low_limit)
  8904			numentries = low_limit;
  8905		if (numentries > max)
  8906			numentries = max;
  8907	
  8908		log2qty = ilog2(numentries);
  8909	
  8910		gfp_flags = (flags & HASH_ZERO) ? GFP_ATOMIC | __GFP_ZERO : GFP_ATOMIC;
  8911		do {
  8912			virt = false;
  8913			size = bucketsize << log2qty;
  8914			if (flags & HASH_EARLY) {
  8915				if (flags & HASH_ZERO)
  8916					table = memblock_alloc(size, SMP_CACHE_BYTES);
  8917				else
  8918					table = memblock_alloc_raw(size,
  8919								   SMP_CACHE_BYTES);
  8920			} else if (get_order(size) >= MAX_ORDER || hashdist) {
> 8921				table = vmalloc_huge(size, gfp_flags);
  8922				virt = true;
  8923				if (table)
  8924					huge = is_vm_area_hugepages(table);
  8925			} else {
  8926				/*
  8927				 * If bucketsize is not a power-of-two, we may free
  8928				 * some pages at the end of hash table which
  8929				 * alloc_pages_exact() automatically does
  8930				 */
  8931				table = alloc_pages_exact(size, gfp_flags);
  8932				kmemleak_alloc(table, size, 1, gfp_flags);
  8933			}
  8934		} while (!table && size > PAGE_SIZE && --log2qty);
  8935	
  8936		if (!table)
  8937			panic("Failed to allocate %s hash table\n", tablename);
  8938	
  8939		pr_info("%s hash table entries: %ld (order: %d, %lu bytes, %s)\n",
  8940			tablename, 1UL << log2qty, ilog2(size) - PAGE_SHIFT, size,
  8941			virt ? (huge ? "vmalloc hugepage" : "vmalloc") : "linear");
  8942	
  8943		if (_hash_shift)
  8944			*_hash_shift = log2qty;
  8945		if (_hash_mask)
  8946			*_hash_mask = (1 << log2qty) - 1;
  8947	
  8948		return table;
  8949	}
  8950
diff mbox series

Patch

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 33ca8cab21e6..0e42038382c1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -8919,7 +8919,7 @@  void *__init alloc_large_system_hash(const char *tablename,
 				table = memblock_alloc_raw(size,
 							   SMP_CACHE_BYTES);
 		} else if (get_order(size) >= MAX_ORDER || hashdist) {
-			table = __vmalloc(size, gfp_flags);
+			table = vmalloc_huge(size, gfp_flags);
 			virt = true;
 			if (table)
 				huge = is_vm_area_hugepages(table);