Created
July 23, 2012 05:20
-
-
Save alexclear/3162059 to your computer and use it in GitHub Desktop.
A patch from https://bugzilla.kernel.org/show_bug.cgi?id=30702 adapted to 2.6.32-042stab057.1-el6-openvz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -u -r .//arch/alpha/include/asm/pgalloc.h ../linux-2.6.32/arch/alpha/include/asm/pgalloc.h | |
--- .//arch/alpha/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/alpha/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -38,10 +38,15 @@ | |
} | |
static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (pmd_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
+ | |
+static inline pmd_t * | |
pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
{ | |
- pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
- return ret; | |
+ return __pmd_alloc_one(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline void | |
@@ -51,10 +56,15 @@ | |
} | |
static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addressi, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
+ | |
+static inline pte_t * | |
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline void | |
diff -u -r .//arch/avr32/include/asm/pgalloc.h ../linux-2.6.32/arch/avr32/include/asm/pgalloc.h | |
--- .//arch/avr32/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/avr32/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -50,10 +50,16 @@ | |
quicklist_free(QUICK_PGD, NULL, pgd); | |
} | |
+static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, | |
+ unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(QUICK_PT, gfp_mask, NULL); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | |
diff -u -r .//arch/cris/include/asm/pgalloc.h ../linux-2.6.32/arch/cris/include/asm/pgalloc.h | |
--- .//arch/cris/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/cris/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -22,10 +22,16 @@ | |
free_page((unsigned long)pgd); | |
} | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *) __get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
diff -u -r .//arch/frv/include/asm/pgalloc.h ../linux-2.6.32/arch/frv/include/asm/pgalloc.h | |
--- .//arch/frv/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/frv/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -35,8 +35,10 @@ | |
extern void pgd_free(struct mm_struct *mm, pgd_t *); | |
extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); | |
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *, unsigned long, gfp_t); | |
extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); | |
+extern pgtable_t __pte_alloc_one(struct mm_struct *, unsigned long, gfp_t); | |
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |
{ | |
@@ -60,6 +62,7 @@ | |
* inside the pgd, so has no extra memory associated with it. | |
* (In the PAE case we free the pmds as part of the pgd.) | |
*/ | |
+#define __pmd_alloc_one(mm, addr,mask) ({ BUG(); ((pmd_t *) 2); }) | |
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *) 2); }) | |
#define pmd_free(mm, x) do { } while (0) | |
#define __pmd_free_tlb(tlb,x,a) do { } while (0) | |
diff -u -r .//arch/frv/include/asm/pgtable.h ../linux-2.6.32/arch/frv/include/asm/pgtable.h | |
--- .//arch/frv/include/asm/pgtable.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/frv/include/asm/pgtable.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -223,6 +223,7 @@ | |
* allocating and freeing a pud is trivial: the 1-entry pud is | |
* inside the pgd, so has no extra memory associated with it. | |
*/ | |
+#define __pud_alloc_one(mm, address, mask) NULL | |
#define pud_alloc_one(mm, address) NULL | |
#define pud_free(mm, x) do { } while (0) | |
#define __pud_free_tlb(tlb, x, address) do { } while (0) | |
diff -u -r .//arch/frv/mm/pgalloc.c ../linux-2.6.32/arch/frv/mm/pgalloc.c | |
--- .//arch/frv/mm/pgalloc.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/frv/mm/pgalloc.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -20,14 +20,19 @@ | |
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); | |
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); | |
+ pte_t *pte = (pte_t *)__get_free_page(gfp_mask); | |
if (pte) | |
clear_page(pte); | |
return pte; | |
} | |
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
{ | |
struct page *page; | |
diff -u -r .//arch/ia64/include/asm/pgalloc.h ../linux-2.6.32/arch/ia64/include/asm/pgalloc.h | |
--- .//arch/ia64/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/ia64/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -39,9 +39,15 @@ | |
pgd_val(*pgd_entry) = __pa(pud); | |
} | |
+static inline pud_t * | |
+__pud_alloc_one(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(0, gfp_mask, NULL); | |
+} | |
+ | |
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | |
{ | |
- return quicklist_alloc(0, GFP_KERNEL, NULL); | |
+ return __pud_alloc_one(mm, addr, GFP_KERNEL); | |
} | |
static inline void pud_free(struct mm_struct *mm, pud_t *pud) | |
@@ -57,9 +63,15 @@ | |
pud_val(*pud_entry) = __pa(pmd); | |
} | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(0, gfp_mask, NULL); | |
+} | |
+ | |
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | |
{ | |
- return quicklist_alloc(0, GFP_KERNEL, NULL); | |
+ return __pmd_alloc_one(mm, addr, GFP_KERNEL); | |
} | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
@@ -95,10 +107,16 @@ | |
return page; | |
} | |
+static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, | |
+ unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(0, gfp_mask, NULL); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long addr) | |
{ | |
- return quicklist_alloc(0, GFP_KERNEL, NULL); | |
+ return __pte_alloc_one_kernel(mm, addr, GFP_KERNEL); | |
} | |
static inline void pte_free(struct mm_struct *mm, pgtable_t pte) | |
diff -u -r .//arch/m32r/include/asm/pgalloc.h ../linux-2.6.32/arch/m32r/include/asm/pgalloc.h | |
--- .//arch/m32r/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/m32r/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -30,12 +30,16 @@ | |
free_page((unsigned long)pgd); | |
} | |
+static __inline__ pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, | |
+ unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
+ | |
static __inline__ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO); | |
- | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL); | |
} | |
static __inline__ pgtable_t pte_alloc_one(struct mm_struct *mm, | |
@@ -66,6 +70,7 @@ | |
* (In the PAE case we free the pmds as part of the pgd.) | |
*/ | |
+#define __pmd_alloc_one(mm, addr,mask) ({ BUG(); ((pmd_t *)2); }) | |
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) | |
#define pmd_free(mm, x) do { } while (0) | |
#define __pmd_free_tlb(tlb, x, addr) do { } while (0) | |
diff -u -r .//arch/m68k/include/asm/motorola_pgalloc.h ../linux-2.6.32/arch/m68k/include/asm/motorola_pgalloc.h | |
--- .//arch/m68k/include/asm/motorola_pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/m68k/include/asm/motorola_pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -5,13 +5,16 @@ | |
#include <asm/tlbflush.h> | |
extern pmd_t *get_pointer_table(void); | |
+extern pmd_t *__get_pointer_table (gfp_t); | |
extern int free_pointer_table(pmd_t *); | |
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
pte_t *pte; | |
- pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
+ pte = (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
if (pte) { | |
__flush_page_to_ram(pte); | |
flush_tlb_kernel_page(pte); | |
@@ -21,6 +24,12 @@ | |
return pte; | |
} | |
+static inline pte_t * | |
+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |
{ | |
cache_page(pte); | |
@@ -61,10 +70,15 @@ | |
__free_page(page); | |
} | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return __get_pointer_table(gfp_mask); | |
+} | |
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
{ | |
- return get_pointer_table(); | |
+ return __pmd_alloc_one(mm, address, GFP_KERNEL); | |
} | |
static inline int pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
diff -u -r .//arch/m68k/include/asm/sun3_pgalloc.h ../linux-2.6.32/arch/m68k/include/asm/sun3_pgalloc.h | |
--- .//arch/m68k/include/asm/sun3_pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/m68k/include/asm/sun3_pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -18,6 +18,7 @@ | |
extern const char bad_pmd_string[]; | |
+#define __pmd_alloc_one(mm,address,mask) ({ BUG(); ((pmd_t *)2); }) | |
#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) | |
@@ -38,10 +39,11 @@ | |
tlb_remove_page((tlb), pte); \ | |
} while (0) | |
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
- unsigned long address) | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
- unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT); | |
+ unsigned long page = __get_free_page(gfp_mask); | |
if (!page) | |
return NULL; | |
@@ -50,6 +52,12 @@ | |
return (pte_t *) (page); | |
} | |
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
+ unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
diff -u -r .//arch/m68k/mm/memory.c ../linux-2.6.32/arch/m68k/mm/memory.c | |
--- .//arch/m68k/mm/memory.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/m68k/mm/memory.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -59,7 +59,7 @@ | |
return; | |
} | |
-pmd_t *get_pointer_table (void) | |
+pmd_t *__get_pointer_table (gfp_t gfp_mask) | |
{ | |
ptable_desc *dp = ptable_list.next; | |
unsigned char mask = PD_MARKBITS (dp); | |
@@ -76,7 +76,7 @@ | |
void *page; | |
ptable_desc *new; | |
- if (!(page = (void *)get_zeroed_page(GFP_KERNEL))) | |
+ if (!(page = (void *)get_zeroed_page(gfp_mask))) | |
return NULL; | |
flush_tlb_kernel_page(page); | |
@@ -99,6 +99,11 @@ | |
return (pmd_t *) (page_address(PD_PAGE(dp)) + off); | |
} | |
+pmd_t *get_pointer_table (void) | |
+{ | |
+ return __get_pointer_table(GFP_KERNEL); | |
+} | |
+ | |
int free_pointer_table (pmd_t *ptable) | |
{ | |
ptable_desc *dp; | |
diff -u -r .//arch/mips/include/asm/pgalloc.h ../linux-2.6.32/arch/mips/include/asm/pgalloc.h | |
--- .//arch/mips/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/mips/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -64,14 +64,16 @@ | |
free_pages((unsigned long)pgd, PGD_ORDER); | |
} | |
+static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, | |
+ unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *) __get_free_pages(gfp_mask | __GFP_ZERO, PTE_ORDER); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- pte_t *pte; | |
- | |
- pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER); | |
- | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline struct page *pte_alloc_one(struct mm_struct *mm, | |
@@ -106,16 +108,22 @@ | |
#ifdef CONFIG_64BIT | |
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
pmd_t *pmd; | |
- pmd = (pmd_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PMD_ORDER); | |
+ pmd = (pmd_t *) __get_free_pages(gfp_mask, PMD_ORDER); | |
if (pmd) | |
pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); | |
return pmd; | |
} | |
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pmd_alloc_one(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
{ | |
free_pages((unsigned long)pmd, PMD_ORDER); | |
diff -u -r .//arch/mn10300/include/asm/pgalloc.h ../linux-2.6.32/arch/mn10300/include/asm/pgalloc.h | |
--- .//arch/mn10300/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/mn10300/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -38,6 +38,8 @@ | |
extern void pgd_free(struct mm_struct *, pgd_t *); | |
extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); | |
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *, unsigned long, gfp_t); | |
+ | |
extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); | |
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |
diff -u -r .//arch/mn10300/mm/pgtable.c ../linux-2.6.32/arch/mn10300/mm/pgtable.c | |
--- .//arch/mn10300/mm/pgtable.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/mn10300/mm/pgtable.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -62,14 +62,20 @@ | |
__flush_tlb_one(vaddr); | |
} | |
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); | |
+ pte_t *pte = (pte_t *)__get_free_page(gfp_mask); | |
if (pte) | |
clear_page(pte); | |
return pte; | |
} | |
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
{ | |
struct page *pte; | |
diff -u -r .//arch/parisc/include/asm/pgalloc.h ../linux-2.6.32/arch/parisc/include/asm/pgalloc.h | |
--- .//arch/parisc/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/parisc/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -61,15 +61,20 @@ | |
(__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)); | |
} | |
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
- pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, | |
- PMD_ORDER); | |
+ pmd_t *pmd = (pmd_t *)__get_free_pages(gfp_mask, PMD_ORDER); | |
if (pmd) | |
memset(pmd, 0, PAGE_SIZE<<PMD_ORDER); | |
return pmd; | |
} | |
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pmd_alloc_one(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
{ | |
#ifdef CONFIG_64BIT | |
@@ -90,6 +95,7 @@ | |
* inside the pgd, so has no extra memory associated with it. | |
*/ | |
+#define __pmd_alloc_one(mm, addr, mask) ({ BUG(); ((pmd_t *)2); }) | |
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) | |
#define pmd_free(mm, x) do { } while (0) | |
#define pgd_populate(mm, pmd, pte) BUG() | |
@@ -127,10 +133,15 @@ | |
} | |
static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
+ | |
+static inline pte_t * | |
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) | |
{ | |
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, addr, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |
diff -u -r .//arch/powerpc/include/asm/pgalloc-32.h ../linux-2.6.32/arch/powerpc/include/asm/pgalloc-32.h | |
--- .//arch/powerpc/include/asm/pgalloc-32.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/powerpc/include/asm/pgalloc-32.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -34,6 +34,8 @@ | |
#endif | |
extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); | |
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *, unsigned long, gfp_t); | |
+ | |
extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr); | |
static inline void pgtable_free(pgtable_free_t pgf) | |
diff -u -r .//arch/powerpc/mm/pgtable_32.c ../linux-2.6.32/arch/powerpc/mm/pgtable_32.c | |
--- .//arch/powerpc/mm/pgtable_32.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/powerpc/mm/pgtable_32.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -93,14 +93,15 @@ | |
#endif | |
} | |
-__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+__init_refok pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
pte_t *pte; | |
extern int mem_init_done; | |
extern void *early_get_page(void); | |
if (mem_init_done) { | |
- pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
+ pte = (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
} else { | |
pte = (pte_t *)early_get_page(); | |
if (pte) | |
@@ -109,6 +110,11 @@ | |
return pte; | |
} | |
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
{ | |
struct page *ptepage; | |
diff -u -r .//arch/score/include/asm/pgalloc.h ../linux-2.6.32/arch/score/include/asm/pgalloc.h | |
--- .//arch/score/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/score/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -37,15 +37,16 @@ | |
free_pages((unsigned long)pgd, PGD_ORDER); | |
} | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *) __get_free_pages(gfp_mask | __GFP_ZERO, PTE_ORDER); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- pte_t *pte; | |
- | |
- pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, | |
- PTE_ORDER); | |
- | |
- return pte; | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline struct page *pte_alloc_one(struct mm_struct *mm, | |
diff -u -r .//arch/sparc/include/asm/pgalloc_32.h ../linux-2.6.32/arch/sparc/include/asm/pgalloc_32.h | |
--- .//arch/sparc/include/asm/pgalloc_32.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/sparc/include/asm/pgalloc_32.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -41,6 +41,9 @@ | |
BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long) | |
#define pmd_alloc_one(mm, address) BTFIXUP_CALL(pmd_alloc_one)(mm, address) | |
+BTFIXUPDEF_CALL(pmd_t *, __pmd_alloc_one, struct mm_struct *, unsigned long, gfp_t) | |
+#define __pmd_alloc_one(mm, address, gfp_mask) BTFIXUP_CALL(pmd_alloc_one)(mm, address) | |
+ | |
BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *) | |
#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd) | |
@@ -57,6 +60,8 @@ | |
#define pte_alloc_one(mm, address) BTFIXUP_CALL(pte_alloc_one)(mm, address) | |
BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long) | |
#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr) | |
+BTFIXUPDEF_CALL(pte_t *, __pte_alloc_one_kernel, struct mm_struct *, unsigned long, gfp_t) | |
+#define __pte_alloc_one_kernel(mm, addr, gfp_mask) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr) | |
BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *) | |
#define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte) | |
diff -u -r .//arch/sparc/include/asm/pgalloc_64.h ../linux-2.6.32/arch/sparc/include/asm/pgalloc_64.h | |
--- .//arch/sparc/include/asm/pgalloc_64.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/sparc/include/asm/pgalloc_64.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -26,9 +26,15 @@ | |
#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(0, gfp_mask, NULL); | |
+} | |
+ | |
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | |
{ | |
- return quicklist_alloc(0, GFP_KERNEL, NULL); | |
+ return __pmd_alloc_one(mm, addr, GFP_KERNEL); | |
} | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
@@ -36,10 +42,17 @@ | |
quicklist_free(0, NULL, pmd); | |
} | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
+{ | |
+ return quicklist_alloc(0, gfp_mask, NULL); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- return quicklist_alloc(0, GFP_KERNEL, NULL); | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL); | |
} | |
static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | |
diff -u -r .//arch/um/include/asm/pgalloc.h ../linux-2.6.32/arch/um/include/asm/pgalloc.h | |
--- .//arch/um/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/um/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -27,6 +27,7 @@ | |
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | |
extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); | |
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *, unsigned long, gfp_t); | |
extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); | |
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |
diff -u -r .//arch/um/kernel/mem.c ../linux-2.6.32/arch/um/kernel/mem.c | |
--- .//arch/um/kernel/mem.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/um/kernel/mem.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -284,12 +284,15 @@ | |
free_page((unsigned long) pgd); | |
} | |
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
- pte_t *pte; | |
+ return (pte_t *)__get_free_page(gfp_mask | __GFP_ZERO); | |
+} | |
- pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | |
- return pte; | |
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
@@ -303,15 +306,21 @@ | |
} | |
#ifdef CONFIG_3_LEVEL_PGTABLES | |
-pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
{ | |
- pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); | |
+ pmd_t *pmd = (pmd_t *) __get_free_page(gfp_mask); | |
if (pmd) | |
memset(pmd, 0, PAGE_SIZE); | |
return pmd; | |
} | |
+ | |
+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pmd_alloc_one(mm, address, GFP_KERNEL); | |
+} | |
#endif | |
void *uml_kmalloc(int size, int flags) | |
diff -u -r .//arch/x86/include/asm/pgalloc.h ../linux-2.6.32/arch/x86/include/asm/pgalloc.h | |
--- .//arch/x86/include/asm/pgalloc.h 2012-07-22 20:40:49.000000000 +0400 | |
+++ ../linux-2.6.32/arch/x86/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -34,6 +34,7 @@ | |
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | |
extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); | |
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *, unsigned long, gfp_t); | |
extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); | |
/* Should really implement gc for free page table pages. This could be | |
@@ -78,9 +79,15 @@ | |
#define pmd_pgtable(pmd) pmd_page(pmd) | |
#if PAGETABLE_LEVELS > 2 | |
+static inline pmd_t * | |
+__pmd_alloc_one(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return (pmd_t *)get_zeroed_page(gfp_mask); | |
+} | |
+ | |
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | |
{ | |
- return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); | |
+ return __pmd_alloc_one(mm, addr, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
@@ -114,9 +121,15 @@ | |
set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud))); | |
} | |
+static inline pud_t * | |
+__pud_alloc_one(struct mm_struct *mm, unsigned long addr, gfp_t gfp_mask) | |
+{ | |
+ return (pud_t *)get_zeroed_page(gfp_mask); | |
+} | |
+ | |
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | |
{ | |
- return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); | |
+ return __pud_alloc_one(mm, addr, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline void pud_free(struct mm_struct *mm, pud_t *pud) | |
diff -u -r .//arch/x86/mm/pgtable.c ../linux-2.6.32/arch/x86/mm/pgtable.c | |
--- .//arch/x86/mm/pgtable.c 2012-07-22 20:40:49.000000000 +0400 | |
+++ ../linux-2.6.32/arch/x86/mm/pgtable.c 2012-07-22 21:18:58.000000000 +0400 | |
@@ -17,9 +17,15 @@ | |
gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP; | |
+pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (pte_t *)__get_free_page(gfp_mask | __GFP_NOTRACK | __GFP_ZERO); | |
+} | |
+ | |
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
{ | |
- return (pte_t *)__get_free_page(PGALLOC_KERN_GFP); | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |
diff -u -r .//arch/xtensa/include/asm/pgalloc.h ../linux-2.6.32/arch/xtensa/include/asm/pgalloc.h | |
--- .//arch/xtensa/include/asm/pgalloc.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/xtensa/include/asm/pgalloc.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -41,10 +41,17 @@ | |
extern struct kmem_cache *pgtable_cache; | |
+static inline pte_t * | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
+{ | |
+ return kmem_cache_alloc(pgtable_cache, gfp_mask); | |
+} | |
+ | |
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
unsigned long address) | |
{ | |
- return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
} | |
static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | |
diff -u -r .//arch/xtensa/mm/pgtable.c ../linux-2.6.32/arch/xtensa/mm/pgtable.c | |
--- .//arch/xtensa/mm/pgtable.c 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/arch/xtensa/mm/pgtable.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -12,13 +12,15 @@ | |
#if (DCACHE_SIZE > PAGE_SIZE) | |
-pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+pte_t* | |
+__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
pte_t *pte = NULL, *p; | |
int color = ADDR_COLOR(address); | |
int i; | |
- p = (pte_t*) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, COLOR_ORDER); | |
+ p = (pte_t*) __get_free_pages(gfp_mask, COLOR_ORDER); | |
if (likely(p)) { | |
split_page(virt_to_page(p), COLOR_ORDER); | |
@@ -35,6 +37,11 @@ | |
return pte; | |
} | |
+pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | |
+{ | |
+ return __pte_alloc_one_kernel(mm, address, GFP_KERNEL | __GFP_REPEAT); | |
+} | |
+ | |
#ifdef PROFILING | |
int mask; | |
diff -u -r .//include/asm-generic/4level-fixup.h ../linux-2.6.32/include/asm-generic/4level-fixup.h | |
--- .//include/asm-generic/4level-fixup.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/include/asm-generic/4level-fixup.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -10,10 +10,14 @@ | |
#define pud_t pgd_t | |
-#define pmd_alloc(mm, pud, address) \ | |
- ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \ | |
+#define pmd_alloc_with_mask(mm, pud, address, mask) \ | |
+ ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address, mask))? \ | |
NULL: pmd_offset(pud, address)) | |
+#define pmd_alloc(mm, pud, address) \ | |
+ pmd_alloc_with_mask(mm, pud, address, GFP_KERNEL) | |
+ | |
+#define pud_alloc_with_mask(mm, pgd, address, mask) (pgd) | |
#define pud_alloc(mm, pgd, address) (pgd) | |
#define pud_offset(pgd, start) (pgd) | |
#define pud_none(pud) 0 | |
diff -u -r .//include/asm-generic/pgtable-nopmd.h ../linux-2.6.32/include/asm-generic/pgtable-nopmd.h | |
--- .//include/asm-generic/pgtable-nopmd.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/include/asm-generic/pgtable-nopmd.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -55,7 +55,8 @@ | |
* allocating and freeing a pmd is trivial: the 1-entry pmd is | |
* inside the pud, so has no extra memory associated with it. | |
*/ | |
-#define pmd_alloc_one(mm, address) NULL | |
+#define __pmd_alloc_one(mm, address, mask) NULL | |
+#define pmd_alloc_one(mm, address) NULL | |
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
{ | |
} | |
diff -u -r .//include/asm-generic/pgtable-nopud.h ../linux-2.6.32/include/asm-generic/pgtable-nopud.h | |
--- .//include/asm-generic/pgtable-nopud.h 2009-12-03 06:51:21.000000000 +0300 | |
+++ ../linux-2.6.32/include/asm-generic/pgtable-nopud.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -50,6 +50,7 @@ | |
* allocating and freeing a pud is trivial: the 1-entry pud is | |
* inside the pgd, so has no extra memory associated with it. | |
*/ | |
+#define __pud_alloc_one(mm, address, mask) NULL | |
#define pud_alloc_one(mm, address) NULL | |
#define pud_free(mm, x) do { } while (0) | |
#define __pud_free_tlb(tlb, x, a) do { } while (0) | |
diff -u -r .//include/linux/mm.h ../linux-2.6.32/include/linux/mm.h | |
--- .//include/linux/mm.h 2012-07-22 20:40:51.000000000 +0400 | |
+++ ../linux-2.6.32/include/linux/mm.h 2012-07-22 21:06:48.000000000 +0400 | |
@@ -1033,44 +1033,60 @@ | |
#ifdef __PAGETABLE_PUD_FOLDED | |
static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, | |
- unsigned long address) | |
+ unsigned long address, gfp_t gfp_mask) | |
{ | |
return 0; | |
} | |
#else | |
-int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address); | |
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address, | |
+ gfp_t gfp_mask); | |
#endif | |
#ifdef __PAGETABLE_PMD_FOLDED | |
static inline int __pmd_alloc(struct mm_struct *mm, pud_t *pud, | |
- unsigned long address) | |
+ unsigned long address, gfp_t gfp_mask) | |
{ | |
return 0; | |
} | |
#else | |
-int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address); | |
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address, | |
+ gfp_t gfp_mask); | |
#endif | |
int __pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, | |
pmd_t *pmd, unsigned long address); | |
-int __pte_alloc_kernel(pmd_t *pmd, unsigned long address); | |
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address, gfp_t gfp_mask); | |
/* | |
* The following ifdef needed to get the 4level-fixup.h header to work. | |
* Remove it when 4level-fixup.h has been removed. | |
*/ | |
#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK) | |
-static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) | |
+static inline pud_t *pud_alloc_with_mask(struct mm_struct *mm, pgd_t *pgd, | |
+ unsigned long address, gfp_t gfp_mask) | |
{ | |
- return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))? | |
+ return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address, gfp_mask))? | |
NULL: pud_offset(pgd, address); | |
} | |
-static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) | |
+static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, | |
+ unsigned long address) | |
{ | |
- return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))? | |
+ return pud_alloc_with_mask(mm, pgd, address, GFP_KERNEL); | |
+} | |
+ | |
+static inline pmd_t *pmd_alloc_with_mask(struct mm_struct *mm, pud_t *pud, | |
+ unsigned long address, gfp_t gfp_mask) | |
+{ | |
+ return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address, gfp_mask))? | |
NULL: pmd_offset(pud, address); | |
} | |
+ | |
+static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, | |
+ unsigned long address) | |
+{ | |
+ return pmd_alloc_with_mask(mm, pud, address, GFP_KERNEL); | |
+} | |
#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */ | |
#if USE_SPLIT_PTLOCKS | |
@@ -1131,8 +1147,12 @@ | |
pmd, address))? \ | |
NULL: pte_offset_map_lock(mm, pmd, address, ptlp)) | |
+#define pte_alloc_kernel_with_mask(pmd, address, mask) \ | |
+ ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address, mask))? \ | |
+ NULL: pte_offset_kernel(pmd, address)) | |
+ | |
#define pte_alloc_kernel(pmd, address) \ | |
- ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \ | |
+ ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address, GFP_KERNEL))? \ | |
NULL: pte_offset_kernel(pmd, address)) | |
extern void free_area_init(unsigned long * zones_size); | |
diff -u -r .//mm/memory.c ../linux-2.6.32/mm/memory.c | |
--- .//mm/memory.c 2012-07-22 20:40:51.000000000 +0400 | |
+++ ../linux-2.6.32/mm/memory.c 2012-07-22 21:15:59.000000000 +0400 | |
@@ -401,9 +401,9 @@ | |
} | |
EXPORT_SYMBOL(__pte_alloc); | |
-int __pte_alloc_kernel(pmd_t *pmd, unsigned long address) | |
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address, gfp_t gfp_mask) | |
{ | |
- pte_t *new = pte_alloc_one_kernel(&init_mm, address); | |
+ pte_t *new = __pte_alloc_one_kernel(&init_mm, address, gfp_mask); | |
if (!new) | |
return -ENOMEM; | |
@@ -3573,9 +3573,10 @@ | |
* Allocate page upper directory. | |
* We've already handled the fast-path in-line. | |
*/ | |
-int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) | |
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
- pud_t *new; | |
+ pud_t *new = __pud_alloc_one(mm, address, gfp_mask); | |
int one; | |
one = ub_page_table_get_one(mm); | |
@@ -3613,9 +3614,10 @@ | |
* Allocate page middle directory. | |
* We've already handled the fast-path in-line. | |
*/ | |
-int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) | |
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address, | |
+ gfp_t gfp_mask) | |
{ | |
- pmd_t *new; | |
+ pmd_t *new = __pmd_alloc_one(mm, address, gfp_mask); | |
int one; | |
one = ub_page_table_get_one(mm); | |
diff -u -r .//mm/vmalloc.c ../linux-2.6.32/mm/vmalloc.c | |
--- .//mm/vmalloc.c 2012-07-22 20:40:51.000000000 +0400 | |
+++ ../linux-2.6.32/mm/vmalloc.c 2012-07-22 21:06:48.000000000 +0400 | |
@@ -90,8 +90,8 @@ | |
} while (pgd++, addr = next, addr != end); | |
} | |
-static int vmap_pte_range(pmd_t *pmd, unsigned long addr, | |
- unsigned long end, pgprot_t prot, struct page **pages, int *nr) | |
+static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |
+ pgprot_t prot, struct page **pages, int *nr, gfp_t gfp_mask) | |
{ | |
pte_t *pte; | |
@@ -100,7 +100,7 @@ | |
* callers keep track of where we're up to. | |
*/ | |
- pte = pte_alloc_kernel(pmd, addr); | |
+ pte = pte_alloc_kernel_with_mask(pmd, addr, gfp_mask); | |
if (!pte) | |
return -ENOMEM; | |
do { | |
@@ -117,34 +117,34 @@ | |
} | |
static int vmap_pmd_range(pud_t *pud, unsigned long addr, | |
- unsigned long end, pgprot_t prot, struct page **pages, int *nr) | |
+ unsigned long end, pgprot_t prot, struct page **pages, int *nr, gfp_t gfp_mask) | |
{ | |
pmd_t *pmd; | |
unsigned long next; | |
- pmd = pmd_alloc(&init_mm, pud, addr); | |
+ pmd = pmd_alloc_with_mask(&init_mm, pud, addr, gfp_mask); | |
if (!pmd) | |
return -ENOMEM; | |
do { | |
next = pmd_addr_end(addr, end); | |
- if (vmap_pte_range(pmd, addr, next, prot, pages, nr)) | |
+ if (vmap_pte_range(pmd, addr, next, prot, pages, nr, gfp_mask)) | |
return -ENOMEM; | |
} while (pmd++, addr = next, addr != end); | |
return 0; | |
} | |
-static int vmap_pud_range(pgd_t *pgd, unsigned long addr, | |
- unsigned long end, pgprot_t prot, struct page **pages, int *nr) | |
+static int vmap_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, | |
+ pgprot_t prot, struct page **pages, int *nr, gfp_t gfp_mask) | |
{ | |
pud_t *pud; | |
unsigned long next; | |
- pud = pud_alloc(&init_mm, pgd, addr); | |
+ pud = pud_alloc_with_mask(&init_mm, pgd, addr, gfp_mask); | |
if (!pud) | |
return -ENOMEM; | |
do { | |
next = pud_addr_end(addr, end); | |
- if (vmap_pmd_range(pud, addr, next, prot, pages, nr)) | |
+ if (vmap_pmd_range(pud, addr, next, prot, pages, nr, gfp_mask)) | |
return -ENOMEM; | |
} while (pud++, addr = next, addr != end); | |
return 0; | |
@@ -156,8 +156,8 @@ | |
* | |
* Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] | |
*/ | |
-static int vmap_page_range_noflush(unsigned long start, unsigned long end, | |
- pgprot_t prot, struct page **pages) | |
+static int __vmap_page_range_noflush(unsigned long start, unsigned long end, | |
+ pgprot_t prot, struct page **pages, gfp_t gfp_mask) | |
{ | |
pgd_t *pgd; | |
unsigned long next; | |
@@ -169,7 +169,7 @@ | |
pgd = pgd_offset_k(addr); | |
do { | |
next = pgd_addr_end(addr, end); | |
- err = vmap_pud_range(pgd, addr, next, prot, pages, &nr); | |
+ err = vmap_pud_range(pgd, addr, next, prot, pages, &nr, gfp_mask); | |
if (err) | |
return err; | |
} while (pgd++, addr = next, addr != end); | |
@@ -177,16 +177,29 @@ | |
return nr; | |
} | |
-static int vmap_page_range(unsigned long start, unsigned long end, | |
- pgprot_t prot, struct page **pages) | |
+ | |
+static int vmap_page_range_noflush(unsigned long start, unsigned long end, | |
+ pgprot_t prot, struct page **pages) | |
+{ | |
+ return __vmap_page_range_noflush(start, end, prot, pages, GFP_KERNEL); | |
+} | |
+ | |
+static int __vmap_page_range(unsigned long start, unsigned long end, | |
+ pgprot_t prot, struct page **pages, gfp_t gfp_mask) | |
{ | |
int ret; | |
- ret = vmap_page_range_noflush(start, end, prot, pages); | |
+ ret = __vmap_page_range_noflush(start, end, prot, pages, gfp_mask); | |
flush_cache_vmap(start, end); | |
return ret; | |
} | |
+static int vmap_page_range(unsigned long start, unsigned long end, | |
+ pgprot_t prot, struct page **pages) | |
+{ | |
+ return __vmap_page_range(start, end, prot, pages, GFP_KERNEL); | |
+} | |
+ | |
int is_vmalloc_or_module_addr(const void *x) | |
{ | |
/* | |
@@ -1196,13 +1209,14 @@ | |
flush_tlb_kernel_range(addr, end); | |
} | |
-int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages) | |
+int __map_vm_area(struct vm_struct *area, pgprot_t prot, | |
+ struct page ***pages, gfp_t gfp_mask) | |
{ | |
unsigned long addr = (unsigned long)area->addr; | |
unsigned long end = addr + area->size - PAGE_SIZE; | |
int err; | |
- err = vmap_page_range(addr, end, prot, *pages); | |
+ err = __vmap_page_range(addr, end, prot, *pages, gfp_mask); | |
if (err > 0) { | |
*pages += err; | |
err = 0; | |
@@ -1210,6 +1224,11 @@ | |
return err; | |
} | |
+ | |
+int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages) | |
+{ | |
+ return __map_vm_area(area, prot, pages, GFP_KERNEL); | |
+} | |
EXPORT_SYMBOL_GPL(map_vm_area); | |
/*** Old vmalloc interfaces ***/ | |
@@ -1534,7 +1553,7 @@ | |
area->pages[i] = page; | |
} | |
- if (map_vm_area(area, prot, &pages)) | |
+ if (__map_vm_area(area, prot, &pages, gfp_mask)) | |
goto fail; | |
inc_vmalloc_charged(area, gfp_mask); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment