This patch allows vm_area_struct can have non hot-pluggable attribute. Pages attached to the vma won't be allocated from hot-pluggable memory area. FIXME: This code is temporary, the base code assumes HighMem is hot-pluggable. The pages should be allocated from non hot-pluggable zone or non hot-pluggable memory area, not from Normal zone. Signed-off-by: Hirokazu Takahashi Signed-off-by: Dave Hansen Index: linux-2.6.13/arch/i386/kernel/sys_i386.c =================================================================== --- linux-2.6.13.orig/arch/i386/kernel/sys_i386.c 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/arch/i386/kernel/sys_i386.c 2005-08-30 12:17:28.000000000 -0700 @@ -70,7 +70,7 @@ asmlinkage long sys_mmap2(unsigned long unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { - return do_mmap2(addr, len, prot, flags, fd, pgoff); + return do_mmap2(addr, len, prot, flags & ~MAP_IMMOVABLE, fd, pgoff); } /* @@ -101,7 +101,8 @@ asmlinkage int old_mmap(struct mmap_arg_ if (a.offset & ~PAGE_MASK) goto out; - err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); + err = do_mmap2(a.addr, a.len, a.prot, a.flags & ~MAP_IMMOVABLE, + a.fd, a.offset >> PAGE_SHIFT); out: return err; } Index: linux-2.6.13/include/asm-i386/mman.h =================================================================== --- linux-2.6.13.orig/include/asm-i386/mman.h 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/include/asm-i386/mman.h 2005-08-30 12:17:28.000000000 -0700 @@ -22,6 +22,7 @@ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define MAP_IMMOVABLE 0x20000 #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ Index: linux-2.6.13/include/asm-ia64/mman.h =================================================================== --- linux-2.6.13.orig/include/asm-ia64/mman.h 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/include/asm-ia64/mman.h 2005-08-30 12:17:28.000000000 -0700 @@ -30,6 +30,7 @@ #define MAP_NORESERVE 0x04000 /* don't check for reservations */ #define MAP_POPULATE 0x08000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define MAP_IMMOVABLE 0x20000 #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ Index: linux-2.6.13/include/linux/mm.h =================================================================== --- linux-2.6.13.orig/include/linux/mm.h 2005-08-30 12:10:12.000000000 -0700 +++ linux-2.6.13/include/linux/mm.h 2005-08-30 12:17:28.000000000 -0700 @@ -161,6 +161,7 @@ extern unsigned int kobjsize(const void #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ +#define VM_IMMOVABLE 0x02000000 /* Don't place in hot removable area */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS Index: linux-2.6.13/include/linux/mman.h =================================================================== --- linux-2.6.13.orig/include/linux/mman.h 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/include/linux/mman.h 2005-08-30 12:17:28.000000000 -0700 @@ -61,7 +61,8 @@ calc_vm_flag_bits(unsigned long flags) return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) | _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) | _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) | - _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ); + _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) | + _calc_vm_trans(flags, MAP_IMMOVABLE, VM_IMMOVABLE ); } #endif /* _LINUX_MMAN_H */ Index: linux-2.6.13/kernel/fork.c =================================================================== --- linux-2.6.13.orig/kernel/fork.c 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/kernel/fork.c 2005-08-30 12:17:28.000000000 -0700 @@ -230,7 +230,7 @@ static inline int dup_mmap(struct mm_str if (IS_ERR(pol)) goto fail_nomem_policy; vma_set_policy(tmp, pol); - tmp->vm_flags &= ~VM_LOCKED; + tmp->vm_flags &= ~(VM_LOCKED|VM_IMMOVABLE); tmp->vm_mm = mm; tmp->vm_next = NULL; anon_vma_link(tmp); Index: linux-2.6.13/mm/memory.c =================================================================== --- linux-2.6.13.orig/mm/memory.c 2005-08-30 12:16:36.000000000 -0700 +++ linux-2.6.13/mm/memory.c 2005-08-30 12:17:28.000000000 -0700 @@ -1279,12 +1279,19 @@ static int do_wp_page(struct mm_struct * if (unlikely(anon_vma_prepare(vma))) goto no_new_page; + if (old_page == ZERO_PAGE(address)) { new_page = alloc_zeroed_user_highpage(vma, address); if (!new_page) goto no_new_page; } else { - new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); +#ifdef CONFIG_MEMORY_HOTPLUG + if (vma->vm_flags & VM_IMMOVABLE) + new_page = alloc_page_vma(GFP_USER, vma, address); + else +#endif + new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); + if (!new_page) goto no_new_page; copy_user_highpage(new_page, old_page, address); @@ -1772,7 +1779,12 @@ do_anonymous_page(struct mm_struct *mm, if (unlikely(anon_vma_prepare(vma))) goto no_mem; - page = alloc_zeroed_user_highpage(vma, addr); +#ifdef CONFIG_MEMORY_HOTPLUG + if (vma->vm_flags & VM_IMMOVABLE) + page = alloc_page_vma(GFP_USER, vma, addr); + else +#endif + page = alloc_zeroed_user_highpage(vma, addr); if (!page) goto no_mem;