diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/arch/i386/Kconfig 112-config_page_offset/arch/i386/Kconfig --- 110-config_hz/arch/i386/Kconfig 2003-12-02 14:53:47.000000000 -0800 +++ 112-config_page_offset/arch/i386/Kconfig 2003-12-02 14:53:57.000000000 -0800 @@ -682,6 +682,44 @@ config HIGHMEM64G endchoice +choice + help + On i386, a process can only virtually address 4GB of memory. This + lets you select how much of that virtual space you would like to + devoted to userspace, and how much to the kernel. + + Some userspace programs would like to address as much as possible and + have few demands of the kernel other than it get out of the way. These + users may opt to use the 3.5GB option to give their userspace program + as much room as possible. Due to alignment issues imposed by PAE, + the "3.5GB" option is unavailable if "64GB" high memory support is + enabled. + + Other users (especially those who use PAE) may be running out of + ZONE_NORMAL memory. Those users may benefit from increasing the + kernel's virtual address space size by taking it away from userspace, + which may not need all of its space. An indicator that this is + happening is when /proc/Meminfo's "LowFree:" is a small percentage of + "LowTotal:" while "HighFree:" is very large. + + If unsure, say "3GB" + prompt "User address space size" + default 1GB + +config 05GB + bool "3.5 GB" + depends on !HIGHMEM64G + +config 1GB + bool "3 GB" + +config 2GB + bool "2 GB" + +config 3GB + bool "1 GB" +endchoice + config HIGHMEM bool depends on HIGHMEM64G || HIGHMEM4G diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/arch/i386/Makefile 112-config_page_offset/arch/i386/Makefile --- 110-config_hz/arch/i386/Makefile 2003-12-02 14:53:24.000000000 -0800 +++ 112-config_page_offset/arch/i386/Makefile 2003-12-02 14:53:57.000000000 -0800 @@ -101,6 +101,7 @@ drivers-$(CONFIG_PM) += arch/i386/powe CFLAGS += $(mflags-y) AFLAGS += $(mflags-y) +AFLAGS_vmlinux.lds.o += -include $(TOPDIR)/include/asm-i386/page.h boot := arch/i386/boot diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/arch/i386/kernel/vmlinux.lds.S 112-config_page_offset/arch/i386/kernel/vmlinux.lds.S --- 110-config_hz/arch/i386/kernel/vmlinux.lds.S 2003-10-01 11:40:41.000000000 -0700 +++ 112-config_page_offset/arch/i386/kernel/vmlinux.lds.S 2003-12-02 14:53:57.000000000 -0800 @@ -10,7 +10,7 @@ ENTRY(startup_32) jiffies = jiffies_64; SECTIONS { - . = 0xC0000000 + 0x100000; + . = __PAGE_OFFSET + 0x100000; /* read-only */ _text = .; /* Text and read-only data */ .text : { diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/include/asm-i386/page.h 112-config_page_offset/include/asm-i386/page.h --- 110-config_hz/include/asm-i386/page.h 2003-04-09 11:48:05.000000000 -0700 +++ 112-config_page_offset/include/asm-i386/page.h 2003-12-02 14:53:57.000000000 -0800 @@ -115,9 +115,26 @@ static __inline__ int get_order(unsigned #endif /* __ASSEMBLY__ */ #ifdef __ASSEMBLY__ -#define __PAGE_OFFSET (0xC0000000) +#include +#ifdef CONFIG_05GB +#define __PAGE_OFFSET (0xE0000000) +#elif defined(CONFIG_1GB) +#define __PAGE_OFFSET (0xC0000000) +#elif defined(CONFIG_2GB) +#define __PAGE_OFFSET (0x80000000) +#elif defined(CONFIG_3GB) +#define __PAGE_OFFSET (0x40000000) +#endif #else -#define __PAGE_OFFSET (0xC0000000UL) +#ifdef CONFIG_05GB +#define __PAGE_OFFSET (0xE0000000UL) +#elif defined(CONFIG_1GB) +#define __PAGE_OFFSET (0xC0000000UL) +#elif defined(CONFIG_2GB) +#define __PAGE_OFFSET (0x80000000UL) +#elif defined(CONFIG_3GB) +#define __PAGE_OFFSET (0x40000000UL) +#endif #endif diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/include/asm-i386/processor.h 112-config_page_offset/include/asm-i386/processor.h --- 110-config_hz/include/asm-i386/processor.h 2003-10-21 11:16:11.000000000 -0700 +++ 112-config_page_offset/include/asm-i386/processor.h 2003-12-02 14:53:57.000000000 -0800 @@ -299,7 +299,11 @@ extern unsigned int mca_pentium_flag; /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ +#ifdef CONFIG_05GB +#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 16)) +#else #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) +#endif /* * Size of io_bitmap, covering ports 0 to 0x3ff. diff -purN -X /home/mbligh/.diff.exclude 110-config_hz/mm/memory.c 112-config_page_offset/mm/memory.c --- 110-config_hz/mm/memory.c 2003-11-24 16:12:33.000000000 -0800 +++ 112-config_page_offset/mm/memory.c 2003-12-02 14:53:57.000000000 -0800 @@ -109,8 +109,7 @@ static inline void free_one_pmd(struct m static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir) { - int j; - pmd_t * pmd; + pmd_t * pmd, * md, * emd; if (pgd_none(*dir)) return; @@ -121,8 +120,21 @@ static inline void free_one_pgd(struct m } pmd = pmd_offset(dir, 0); pgd_clear(dir); - for (j = 0; j < PTRS_PER_PMD ; j++) - free_one_pmd(tlb, pmd+j); + /* + * Beware if changing the loop below. It once used int j, + * for (j = 0; j < PTRS_PER_PMD; j++) + * free_one_pmd(pmd+j); + * but some older i386 compilers (e.g. egcs-2.91.66, gcc-2.95.3) + * terminated the loop with a _signed_ address comparison + * using "jle", when configured for HIGHMEM64GB (X86_PAE). + * If also configured for 3GB of kernel virtual address space, + * if page at physical 0x3ffff000 virtual 0x7ffff000 is used as + * a pmd, when that mm exits the loop goes on to free "entries" + * found at 0x80000000 onwards. The loop below compiles instead + * to be terminated by unsigned address comparison using "jb". + */ + for (md = pmd, emd = pmd + PTRS_PER_PMD; md < emd; md++) + free_one_pmd(tlb,md); pmd_free_tlb(tlb, pmd); }