From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jack Steiner Date: Fri, 20 Feb 2004 01:07:31 +0000 Subject: HUGEPAGE SIZE a boottime option Message-Id: <20040220010731.GA28820@sgi.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-ia64@vger.kernel.org Here is a preliminary version of a patch that makes the size of HUGEPAGES a boottime option. Only ia64-specific files are changed (except for the Documentation file). We have a number of customers using large pages. Unfortunately, the "optimum" size of a large page is application & configuration dependent. Rather that having each customer recompile to specify their own HUGEPAGESIZE, this patch make the size a boottime option. Does this patch look reasonable? If so, I will incorporate feedback, finish testing it, update it to 2.6.3 & resubmit. ------------------------------------------------------------------------- Based on 2.6.2-mm. --- linux.base/Documentation/vm/hugetlbpage.txt Tue Feb 3 21:43:11 2004 +++ linux/Documentation/vm/hugetlbpage.txt Thu Feb 19 16:17:16 2004 @@ -63,6 +63,22 @@ kernel to request huge pages early in the boot process (when the possibility of getting physical contiguous pages is still very high). +Another option is to add the following boot command line option: + + hugepages=xxxx + +The value xxxx specifies the number of hugepages that should be reserved +at boot time. + +Some architectures (ia64) support an additional boot line option to specify +the hugepage size at boot time. If this option is not specified, the hugepage +size defaults to the value specified in the .config file. + + hugepagesz=xxxx + +The value of xxxx is any valid pagesize (256k, ... 256m, etc). + + If the user applications are going to request hugepages using mmap system call, then it is required that system administrator mount a file system of type hugetlbfs: --- linux.base/arch/ia64/kernel/ivt.S Tue Feb 3 21:43:15 2004 +++ linux/arch/ia64/kernel/ivt.S Thu Feb 19 16:10:01 2004 @@ -118,10 +118,8 @@ #ifdef CONFIG_HUGETLB_PAGE extr.u r26=r25,2,6 ;; - cmp.eq p8,p0=HPAGE_SHIFT,r26 - ;; + UPDATE_HPAGE_REGISTERS(p8, r26, r22) // if hugepage, set p8 & update pte index (p8) dep r25=r18,r25,2,6 -(p8) shr r22=r22,HPAGE_SHIFT-PAGE_SHIFT #endif ;; cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? --- linux.base/arch/ia64/kernel/patch.c Tue Feb 3 21:44:04 2004 +++ linux/arch/ia64/kernel/patch.c Thu Feb 19 15:39:02 2004 @@ -107,6 +107,24 @@ ia64_srlz_i(); } +/* + * Patch the vhpt_miss handler with the actual size of huge pages. + */ +void __init +ia64_patch_hugepage(unsigned long addr, long hpageshift) +{ + s32 *offp = (s32 *) addr; + u64 ip; + + ip = (u64) offp + *offp; + ia64_patch(ip, 0x000fe000UL, hpageshift << 13); + ia64_patch(ip+2, 0xfc0fc000UL, ((64-hpageshift+PAGE_SHIFT-1) << 27) + | ((hpageshift-PAGE_SHIFT) << 14)); + + ia64_sync_i(); + ia64_srlz_i(); +} + void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end) { --- linux.base/arch/ia64/kernel/vmlinux.lds.S Tue Feb 3 21:44:27 2004 +++ linux/arch/ia64/kernel/vmlinux.lds.S Thu Feb 19 09:01:31 2004 @@ -56,6 +56,13 @@ __stop___ex_table = .; } + .data.patch.hugepage : AT(ADDR(.data.patch.hugepage) - LOAD_OFFSET) + { + __start___hugepage_patchlist = .; + *(.data.patch.hugepage) + __end___hugepage_patchlist = .; + } + .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) { __start___vtop_patchlist = .; --- linux.base/arch/ia64/mm/hugetlbpage.c Tue Feb 3 21:43:49 2004 +++ linux/arch/ia64/mm/hugetlbpage.c Thu Feb 19 12:25:51 2004 @@ -13,16 +13,20 @@ #include #include #include +#include #include #include +#include #include #include +#include #define TASK_HPAGE_BASE (REGION_HPAGE << REGION_SHIFT) static long htlbpagemem; int htlbpage_max; static long htlbzone_pages; +int hpage_shift=HPAGE_SHIFT_DEFAULT; static struct list_head hugepage_freelists[MAX_NUMNODES]; static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; @@ -520,6 +524,35 @@ } __setup("hugepages=", hugetlb_setup); +static int __init hugetlb_setup_sz(char *s) +{ + long long size; + u64 tr_pages; + long pageshift; + char *rest; + extern void ia64_patch_hugepage(unsigned long, long); + + if (ia64_pal_vm_page_size(&tr_pages, 0) !=0) + return 1; + size = memparse(s, &rest); + if (*rest || (size & (size-1))) + goto bad; + + pageshift = __ffs(size); + if (!(tr_pages & (1UL<