Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/mm: Split hash page table sizing heuristic into a helper

htab_get_table_size() either retrieve the size of the hash page table (HPT)
from the device tree - if the HPT size is determined by firmware - or
uses a heuristic to determine a good size based on RAM size if the kernel
is responsible for allocating the HPT.

To support a PAPR extension allowing resizing of the HPT, we're going to
want the memory size -> HPT size logic elsewhere, so split it out into a
helper function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

David Gibson and committed by
Michael Ellerman
5c3c7ede 1dace6c6

+24 -13
+3
arch/powerpc/include/asm/mmu-hash64.h
··· 608 608 context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; 609 609 return get_vsid(context, ea, ssize); 610 610 } 611 + 612 + unsigned htab_shift_for_mem_size(unsigned long mem_size); 613 + 611 614 #endif /* __ASSEMBLY__ */ 612 615 613 616 #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
+21 -13
arch/powerpc/mm/hash_utils_64.c
··· 609 609 return 0; 610 610 } 611 611 612 + unsigned htab_shift_for_mem_size(unsigned long mem_size) 613 + { 614 + unsigned memshift = __ilog2(mem_size); 615 + unsigned pshift = mmu_psize_defs[mmu_virtual_psize].shift; 616 + unsigned pteg_shift; 617 + 618 + /* round mem_size up to next power of 2 */ 619 + if ((1UL << memshift) < mem_size) 620 + memshift += 1; 621 + 622 + /* aim for 2 pages / pteg */ 623 + pteg_shift = memshift - (pshift + 1); 624 + 625 + /* 626 + * 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab 627 + * size permitted by the architecture. 628 + */ 629 + return max(pteg_shift + 7, 18U); 630 + } 631 + 612 632 static unsigned long __init htab_get_table_size(void) 613 633 { 614 - unsigned long mem_size, rnd_mem_size, pteg_count, psize; 615 - 616 634 /* If hash size isn't already provided by the platform, we try to 617 635 * retrieve it from the device-tree. If it's not there neither, we 618 636 * calculate it now based on the total RAM size ··· 640 622 if (ppc64_pft_size) 641 623 return 1UL << ppc64_pft_size; 642 624 643 - /* round mem_size up to next power of 2 */ 644 - mem_size = memblock_phys_mem_size(); 645 - rnd_mem_size = 1UL << __ilog2(mem_size); 646 - if (rnd_mem_size < mem_size) 647 - rnd_mem_size <<= 1; 648 - 649 - /* # pages / 2 */ 650 - psize = mmu_psize_defs[mmu_virtual_psize].shift; 651 - pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11); 652 - 653 - return pteg_count << 7; 625 + return 1UL << htab_shift_for_mem_size(memblock_phys_mem_size()); 654 626 } 655 627 656 628 #ifdef CONFIG_MEMORY_HOTPLUG