Skip to contentSkip to conversation

track pte pages and use in OOM score

RFC PATCH In review Dave Hansen 3 participants 8 messages Apr 15, 2011 – Apr 26, 2011

Subsystems (19)
lore
Share & tools
lore
#0 lore raw

cover track pte pages and use in OOM score

PTE pages are a relatively invisible memory user. Neither users nor the kernel have any way of telling how many of them any given application is using. Nefarious applications can also potentially tie up lagre amounts of memory in them:

	foo = malloc(big);
	touch(foo);
	madvise(foo, big, MADV_DONTNEED);

That'll leave you with no RSS for "foo", but the pagetable pages will still be there. Do that enough times, and you can potentially harm the system. Even worse, the OOM killer will not necessarily go after such an application since the kernel has no record of the pages.

For the containers and OpenVZ folks, pte pages are one of the main consumers of kernel memory. They should be able to use this code as well.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#1 lore raw

RFC PATCH 1/3 pass mm in to pgtable ctor/dtor

The pagetable page constructor and destructor functions are handy places to hook in our new accounting. But, if we are going to store the accounting in the mm, we need the mm passed in to these functions as well.

---

 linux-2.6.git-dave/arch/alpha/include/asm/pgalloc.h         |    4 ++--
 linux-2.6.git-dave/arch/arm/include/asm/pgalloc.h           |    4 ++--
 linux-2.6.git-dave/arch/arm/include/asm/tlb.h               |    2 +-
 linux-2.6.git-dave/arch/avr32/include/asm/pgalloc.h         |    6 +++---
 linux-2.6.git-dave/arch/cris/include/asm/pgalloc.h          |    6 +++---
 linux-2.6.git-dave/arch/frv/include/asm/pgalloc.h           |    4 ++--
 linux-2.6.git-dave/arch/frv/mm/pgalloc.c                    |    2 +-
 linux-2.6.git-dave/arch/ia64/include/asm/pgalloc.h          |    4 ++--
 linux-2.6.git-dave/arch/m32r/include/asm/pgalloc.h          |    4 ++--
 linux-2.6.git-dave/arch/m68k/include/asm/motorola_pgalloc.h |    6 +++---
 linux-2.6.git-dave/arch/m68k/include/asm/sun3_pgalloc.h     |    6 +++---
 linux-2.6.git-dave/arch/mips/include/asm/pgalloc.h          |    6 +++---
 linux-2.6.git-dave/arch/parisc/include/asm/pgalloc.h        |    4 ++--
 linux-2.6.git-dave/arch/powerpc/include/asm/pgalloc-64.h    |    2 +-
 linux-2.6.git-dave/arch/powerpc/include/asm/pgalloc.h       |    4 ++--
 linux-2.6.git-dave/arch/powerpc/mm/pgtable_32.c             |    2 +-
 linux-2.6.git-dave/arch/s390/mm/pgtable.c                   |    6 +++---
 linux-2.6.git-dave/arch/score/include/asm/pgalloc.h         |    6 +++---
 linux-2.6.git-dave/arch/sh/include/asm/pgalloc.h            |    6 +++---
 linux-2.6.git-dave/arch/sparc/include/asm/pgalloc_64.h      |    4 ++--
 linux-2.6.git-dave/arch/sparc/mm/srmmu.c                    |    6 +++---
 linux-2.6.git-dave/arch/sparc/mm/sun4c.c                    |    6 +++---
 linux-2.6.git-dave/arch/tile/mm/pgtable.c                   |    6 +++---
 linux-2.6.git-dave/arch/um/include/asm/pgalloc.h            |    4 ++--
 linux-2.6.git-dave/arch/um/kernel/mem.c                     |    2 +-
 linux-2.6.git-dave/arch/unicore32/include/asm/pgalloc.h     |    4 ++--
 linux-2.6.git-dave/arch/unicore32/include/asm/tlb.h         |    2 +-
 linux-2.6.git-dave/arch/x86/include/asm/pgalloc.h           |    2 +-
 linux-2.6.git-dave/arch/x86/mm/pgtable.c                    |    4 ++--
 linux-2.6.git-dave/arch/xtensa/include/asm/pgalloc.h        |    4 ++--
 linux-2.6.git-dave/include/linux/mm.h                       |    4 ++--
 31 files changed, 66 insertions(+), 66 deletions(-)
arch/alpha/include/asm/pgalloc.h renamed from arch/alpha/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/alpha/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/alpha/include/asm/pgalloc.h
@@ -72,14 +72,14 @@ pte_alloc_one(struct mm_struct *mm, unsi
 	if (!pte)
 		return NULL;
 	page = virt_to_page(pte);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
 static inline void
 pte_free(struct mm_struct *mm, pgtable_t page)
 {
-	pgtable_page_dtor(page);
+	pgtable_page_dtor(mm, page);
 	__free_page(page);
 }
 
arch/arm/include/asm/pgalloc.h renamed from arch/arm/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/arm/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/arm/include/asm/pgalloc.h
@@ -83,7 +83,7 @@ pte_alloc_one(struct mm_struct *mm, unsi
 	if (pte) {
 		if (!PageHighMem(pte))
 			clean_pte_table(page_address(pte));
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	}
 
 	return pte;
@@ -100,7 +100,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
arch/arm/include/asm/tlb.h renamed from arch/arm/include/asm/tlb.h~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/arm/include/asm/tlb.h~pass-mm-in-to-pgtable-ctor-dtor arch/arm/include/asm/tlb.h
@@ -176,7 +176,7 @@ static inline void tlb_remove_page(struc
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 	unsigned long addr)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	tlb_add_flush(tlb, addr);
 	tlb_remove_page(tlb, pte);
 }
arch/avr32/include/asm/pgalloc.h renamed from arch/avr32/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/avr32/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/avr32/include/asm/pgalloc.h
@@ -68,7 +68,7 @@ static inline pgtable_t pte_alloc_one(st
 		return NULL;
 
 	page = virt_to_page(pg);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 
 	return page;
 }
@@ -80,13 +80,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	quicklist_free_page(QUICK_PT, NULL, pte);
 }
 
 #define __pte_free_tlb(tlb,pte,addr)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
arch/cris/include/asm/pgalloc.h renamed from arch/cris/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/cris/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/cris/include/asm/pgalloc.h
@@ -32,7 +32,7 @@ static inline pgtable_t pte_alloc_one(st
 {
 	struct page *pte;
 	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-	pgtable_page_ctor(pte);
+	pgtable_page_ctor(mm, pte);
 	return pte;
 }
 
@@ -43,13 +43,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
 #define __pte_free_tlb(tlb,pte,address)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
arch/frv/include/asm/pgalloc.h renamed from arch/frv/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/frv/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/frv/include/asm/pgalloc.h
@@ -45,13 +45,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
 #define __pte_free_tlb(tlb,pte,address)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb),(pte));			\
 } while (0)
 
arch/frv/mm/pgalloc.c renamed from arch/frv/mm/pgalloc.c~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/frv/mm/pgalloc.c~pass-mm-in-to-pgtable-ctor-dtor arch/frv/mm/pgalloc.c
@@ -39,7 +39,7 @@ pgtable_t pte_alloc_one(struct mm_struct
 #endif
 	if (page) {
 		clear_highpage(page);
-		pgtable_page_ctor(page);
+		pgtable_page_ctor(mm, page);
 		flush_dcache_page(page);
 	}
 	return page;
arch/ia64/include/asm/pgalloc.h renamed from arch/ia64/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/ia64/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/ia64/include/asm/pgalloc.h
@@ -91,7 +91,7 @@ static inline pgtable_t pte_alloc_one(st
 	if (!pg)
 		return NULL;
 	page = virt_to_page(pg);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -103,7 +103,7 @@ static inline pte_t *pte_alloc_one_kerne
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	quicklist_free_page(0, NULL, pte);
 }
 
arch/m32r/include/asm/pgalloc.h renamed from arch/m32r/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/m32r/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/m32r/include/asm/pgalloc.h
@@ -43,7 +43,7 @@ static __inline__ pgtable_t pte_alloc_on
 {
 	struct page *pte = alloc_page(GFP_KERNEL|__GFP_ZERO);
 
-	pgtable_page_ctor(pte);
+	pgtable_page_ctor(mm, pte);
 	return pte;
 }
 
@@ -54,7 +54,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
arch/m68k/include/asm/motorola_pgalloc.h renamed from arch/m68k/include/asm/motorola_pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/m68k/include/asm/motorola_pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/m68k/include/asm/motorola_pgalloc.h
@@ -40,13 +40,13 @@ static inline pgtable_t pte_alloc_one(st
 	flush_tlb_kernel_page(pte);
 	nocache_page(pte);
 	kunmap(page);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t page)
 {
-	pgtable_page_dtor(page);
+	pgtable_page_dtor(mm, pte);
 	cache_page(kmap(page));
 	kunmap(page);
 	__free_page(page);
@@ -55,7 +55,7 @@ static inline void pte_free(struct mm_st
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
 				  unsigned long address)
 {
-	pgtable_page_dtor(page);
+	pgtable_page_dtor(mm, pte);
 	cache_page(kmap(page));
 	kunmap(page);
 	__free_page(page);
arch/m68k/include/asm/sun3_pgalloc.h renamed from arch/m68k/include/asm/sun3_pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/m68k/include/asm/sun3_pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/m68k/include/asm/sun3_pgalloc.h
@@ -28,13 +28,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t page)
 {
-	pgtable_page_dtor(page);
+	pgtable_page_dtor(mm, pte);
         __free_page(page);
 }
 
 #define __pte_free_tlb(tlb,pte,addr)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
@@ -59,7 +59,7 @@ static inline pgtable_t pte_alloc_one(st
 		return NULL;
 
 	clear_highpage(page);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 
 }
arch/mips/include/asm/pgalloc.h renamed from arch/mips/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/mips/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/mips/include/asm/pgalloc.h
@@ -82,7 +82,7 @@ static inline struct page *pte_alloc_one
 	pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
 	if (pte) {
 		clear_highpage(pte);
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	}
 	return pte;
 }
@@ -94,13 +94,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_pages(pte, PTE_ORDER);
 }
 
 #define __pte_free_tlb(tlb,pte,address)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
arch/parisc/include/asm/pgalloc.h renamed from arch/parisc/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/parisc/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/parisc/include/asm/pgalloc.h
@@ -122,7 +122,7 @@ pte_alloc_one(struct mm_struct *mm, unsi
 {
 	struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	if (page)
-		pgtable_page_ctor(page);
+		pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -140,7 +140,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, struct page *pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	pte_free_kernel(mm, page_address(pte));
 }
 
arch/powerpc/include/asm/pgalloc-64.h renamed from arch/powerpc/include/asm/pgalloc-64.h~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/powerpc/include/asm/pgalloc-64.h~pass-mm-in-to-pgtable-ctor-dtor arch/powerpc/include/asm/pgalloc-64.h
@@ -116,7 +116,7 @@ static inline pgtable_t pte_alloc_one(st
 	if (!pte)
 		return NULL;
 	page = virt_to_page(pte);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
arch/powerpc/include/asm/pgalloc.h renamed from arch/powerpc/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/powerpc/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/powerpc/include/asm/pgalloc.h
@@ -20,7 +20,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
 {
-	pgtable_page_dtor(ptepage);
+	pgtable_page_dtor(mm, ptepage);
 	__free_page(ptepage);
 }
 
@@ -45,7 +45,7 @@ static inline void __pte_free_tlb(struct
 				  unsigned long address)
 {
 	tlb_flush_pgtable(tlb, address);
-	pgtable_page_dtor(ptepage);
+	pgtable_page_dtor(tlb->mm, ptepage);
 	pgtable_free_tlb(tlb, page_address(ptepage), 0);
 }
 
arch/powerpc/mm/pgtable_32.c renamed from arch/powerpc/mm/pgtable_32.c~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/powerpc/mm/pgtable_32.c~pass-mm-in-to-pgtable-ctor-dtor arch/powerpc/mm/pgtable_32.c
@@ -120,7 +120,7 @@ pgtable_t pte_alloc_one(struct mm_struct
 	ptepage = alloc_pages(flags, 0);
 	if (!ptepage)
 		return NULL;
-	pgtable_page_ctor(ptepage);
+	pgtable_page_ctor(mm, ptepage);
 	return ptepage;
 }
 
arch/s390/mm/pgtable.c renamed from arch/s390/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/s390/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor arch/s390/mm/pgtable.c
@@ -287,7 +287,7 @@ unsigned long *page_table_alloc(struct m
 		page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
 		if (!page)
 			return NULL;
-		pgtable_page_ctor(page);
+		pgtable_page_ctor(mm, page);
 		page->flags &= ~FRAG_MASK;
 		table = (unsigned long *) page_to_phys(page);
 		if (mm->context.has_pgste)
@@ -319,7 +319,7 @@ static void __page_table_free(struct mm_
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
 	page->flags ^= bits;
 	if (!(page->flags & FRAG_MASK)) {
-		pgtable_page_dtor(page);
+		pgtable_page_dtor(mm, page);
 		__free_page(page);
 	}
 }
@@ -344,7 +344,7 @@ void page_table_free(struct mm_struct *m
 		list_del(&page->lru);
 	spin_unlock_bh(&mm->context.list_lock);
 	if (page) {
-		pgtable_page_dtor(page);
+		pgtable_page_dtor(mm, page);
 		__free_page(page);
 	}
 }
arch/score/include/asm/pgalloc.h renamed from arch/score/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/score/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/score/include/asm/pgalloc.h
@@ -56,7 +56,7 @@ static inline struct page *pte_alloc_one
 	pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
 	if (pte) {
 		clear_highpage(pte);
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	}
 	return pte;
 }
@@ -68,13 +68,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, page);
 	__free_pages(pte, PTE_ORDER);
 }
 
 #define __pte_free_tlb(tlb, pte, buf)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
arch/sh/include/asm/pgalloc.h renamed from arch/sh/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/sh/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/sh/include/asm/pgalloc.h
@@ -47,7 +47,7 @@ static inline pgtable_t pte_alloc_one(st
 	if (!pg)
 		return NULL;
 	page = virt_to_page(pg);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -58,13 +58,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, page);
 	quicklist_free_page(QUICK_PT, NULL, pte);
 }
 
 #define __pte_free_tlb(tlb,pte,addr)			\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb), (pte));			\
 } while (0)
 
arch/sparc/include/asm/pgalloc_64.h renamed from arch/sparc/include/asm/pgalloc_64.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/sparc/include/asm/pgalloc_64.h~pass-mm-in-to-pgtable-ctor-dtor arch/sparc/include/asm/pgalloc_64.h
@@ -52,7 +52,7 @@ static inline pgtable_t pte_alloc_one(st
 	if (!pg)
 		return NULL;
 	page = virt_to_page(pg);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -63,7 +63,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
 {
-	pgtable_page_dtor(ptepage);
+	pgtable_page_dtor(mm, ptepage);
 	quicklist_free_page(0, NULL, ptepage);
 }
 
arch/sparc/mm/srmmu.c renamed from arch/sparc/mm/srmmu.c~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/sparc/mm/srmmu.c~pass-mm-in-to-pgtable-ctor-dtor arch/sparc/mm/srmmu.c
@@ -500,7 +500,7 @@ srmmu_pte_alloc_one(struct mm_struct *mm
 	if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) == 0)
 		return NULL;
 	page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -509,11 +509,11 @@ static void srmmu_free_pte_fast(pte_t *p
 	srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
 }
 
-static void srmmu_pte_free(pgtable_t pte)
+static void srmmu_pte_free(struct mm_struct *mm, pgtable_t pte)
 {
 	unsigned long p;
 
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	p = (unsigned long)page_address(pte);	/* Cached address (for test) */
 	if (p == 0)
 		BUG();
arch/sparc/mm/sun4c.c renamed from arch/sparc/mm/sun4c.c~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/sparc/mm/sun4c.c~pass-mm-in-to-pgtable-ctor-dtor arch/sparc/mm/sun4c.c
@@ -1842,7 +1842,7 @@ static pgtable_t sun4c_pte_alloc_one(str
 	if (pte == NULL)
 		return NULL;
 	page = virt_to_page(pte);
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -1853,9 +1853,9 @@ static inline void sun4c_free_pte_fast(p
 	pgtable_cache_size++;
 }
 
-static void sun4c_pte_free(pgtable_t pte)
+static void sun4c_pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	sun4c_free_pte_fast(page_address(pte));
 }
 
arch/tile/mm/pgtable.c renamed from arch/tile/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor +3 -3
diff -puN arch/tile/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor arch/tile/mm/pgtable.c
@@ -316,7 +316,7 @@ struct page *pte_alloc_one(struct mm_str
 	}
 #endif
 
-	pgtable_page_ctor(p);
+	pgtable_page_ctor(mm, p);
 	return p;
 }
 
@@ -329,7 +329,7 @@ void pte_free(struct mm_struct *mm, stru
 {
 	int i;
 
-	pgtable_page_dtor(p);
+	pgtable_page_dtor(mm, p);
 	__free_page(p);
 
 	for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) {
@@ -343,7 +343,7 @@ void __pte_free_tlb(struct mmu_gather *t
 {
 	int i;
 
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(tlb->mm, pte);
 	tlb_remove_page(tlb, pte);
 
 	for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) {
arch/um/include/asm/pgalloc.h renamed from arch/um/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/um/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/um/include/asm/pgalloc.h
@@ -36,13 +36,13 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
 #define __pte_free_tlb(tlb,pte, address)		\
 do {							\
-	pgtable_page_dtor(pte);				\
+	pgtable_page_dtor((tlb)->mm, pte);		\
 	tlb_remove_page((tlb),(pte));			\
 } while (0)
 
arch/um/kernel/mem.c renamed from arch/um/kernel/mem.c~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/um/kernel/mem.c~pass-mm-in-to-pgtable-ctor-dtor arch/um/kernel/mem.c
@@ -298,7 +298,7 @@ pgtable_t pte_alloc_one(struct mm_struct
 
 	pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	if (pte)
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	return pte;
 }
 
arch/unicore32/include/asm/pgalloc.h renamed from arch/unicore32/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/unicore32/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/unicore32/include/asm/pgalloc.h
@@ -56,7 +56,7 @@ pte_alloc_one(struct mm_struct *mm, unsi
 			void *page = page_address(pte);
 			clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t));
 		}
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	}
 
 	return pte;
@@ -73,7 +73,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
arch/unicore32/include/asm/tlb.h renamed from arch/unicore32/include/asm/tlb.h~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/unicore32/include/asm/tlb.h~pass-mm-in-to-pgtable-ctor-dtor arch/unicore32/include/asm/tlb.h
@@ -19,7 +19,7 @@
 
 #define __pte_free_tlb(tlb, pte, addr)				\
 	do {							\
-		pgtable_page_dtor(pte);				\
+		pgtable_page_dtor((tlb)->mm, pte);		\
 		tlb_remove_page((tlb), (pte));			\
 	} while (0)
 
arch/x86/include/asm/pgalloc.h renamed from arch/x86/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +1 -1
diff -puN arch/x86/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/x86/include/asm/pgalloc.h
@@ -47,7 +47,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, struct page *pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	__free_page(pte);
 }
 
arch/x86/mm/pgtable.c renamed from arch/x86/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/x86/mm/pgtable.c~pass-mm-in-to-pgtable-ctor-dtor arch/x86/mm/pgtable.c
@@ -26,7 +26,7 @@ pgtable_t pte_alloc_one(struct mm_struct
 
 	pte = alloc_pages(__userpte_alloc_gfp, 0);
 	if (pte)
-		pgtable_page_ctor(pte);
+		pgtable_page_ctor(mm, pte);
 	return pte;
 }
 
@@ -49,7 +49,7 @@ early_param("userpte", setup_userpte);
 
 void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(tlb->mm, pte);
 	paravirt_release_pte(page_to_pfn(pte));
 	tlb_remove_page(tlb, pte);
 }
arch/xtensa/include/asm/pgalloc.h renamed from arch/xtensa/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN arch/xtensa/include/asm/pgalloc.h~pass-mm-in-to-pgtable-ctor-dtor arch/xtensa/include/asm/pgalloc.h
@@ -54,7 +54,7 @@ static inline pgtable_t pte_alloc_one(st
 	struct page *page;
 
 	page = virt_to_page(pte_alloc_one_kernel(mm, addr));
-	pgtable_page_ctor(page);
+	pgtable_page_ctor(mm, page);
 	return page;
 }
 
@@ -65,7 +65,7 @@ static inline void pte_free_kernel(struc
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 {
-	pgtable_page_dtor(pte);
+	pgtable_page_dtor(mm, pte);
 	kmem_cache_free(pgtable_cache, page_address(pte));
 }
 #define pmd_pgtable(pmd) pmd_page(pmd)
include/linux/mm.h renamed from include/linux/mm.h~pass-mm-in-to-pgtable-ctor-dtor +2 -2
diff -puN include/linux/mm.h~pass-mm-in-to-pgtable-ctor-dtor include/linux/mm.h
@@ -1242,13 +1242,13 @@ static inline pmd_t *pmd_alloc(struct mm
 #define pte_lockptr(mm, pmd)	({(void)(pmd); &(mm)->page_table_lock;})
 #endif /* USE_SPLIT_PTLOCKS */
 
-static inline void pgtable_page_ctor(struct page *page)
+static inline void pgtable_page_ctor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_init(page);
 	inc_zone_page_state(page, NR_PAGETABLE);
 }
 
-static inline void pgtable_page_dtor(struct page *page)
+static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_deinit(page);
 	dec_zone_page_state(page, NR_PAGETABLE);

_

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw

RFC PATCH 2/3 track numbers of pagetable pages

In reply to Dave Hansen

Now that we have the mm in the constructor and destructor, it's simple to to bump a counter. Add the counter to the mm and use the existing MM_* counter infrastructure.

---

 linux-2.6.git-dave/include/linux/mm.h       |    2 ++
 linux-2.6.git-dave/include/linux/mm_types.h |    1 +
 2 files changed, 3 insertions(+)
include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +2 -0
diff -puN include/linux/mm.h~track-pagetable-pages include/linux/mm.h
@@ -1245,12 +1245,14 @@ static inline pmd_t *pmd_alloc(struct mm
 static inline void pgtable_page_ctor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_init(page);
+	inc_mm_counter(mm, MM_PTEPAGES);
 	inc_zone_page_state(page, NR_PAGETABLE);
 }
 
 static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_deinit(page);
+	dec_mm_counter(mm, MM_PTEPAGES);
 	dec_zone_page_state(page, NR_PAGETABLE);
 }
 
include/linux/mm_types.h renamed from include/linux/mm_types.h~track-pagetable-pages +1 -0
diff -puN include/linux/mm_types.h~track-pagetable-pages include/linux/mm_types.h
@@ -200,6 +200,7 @@ enum {
 	MM_FILEPAGES,
 	MM_ANONPAGES,
 	MM_SWAPENTS,
+	MM_PTEPAGES,
 	NR_MM_COUNTERS
 };
 

_

#3 lore raw

Re: [RFC][PATCH 2/3] track numbers of pagetable pages

Quoted 19 lines · On Fri, 15 Apr 2011 10:38:23 -0700 Dave Hansen <[email protected]> wrote:

Now that we have the mm in the constructor and destructor, it's simple to to bump a counter. Add the counter to the mm and use the existing MM_* counter infrastructure.

---

 linux-2.6.git-dave/include/linux/mm.h       |    2 ++
 linux-2.6.git-dave/include/linux/mm_types.h |    1 +
 2 files changed, 3 insertions(+)

diff -puN include/linux/mm.h~track-pagetable-pages include/linux/mm.h

include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +0 -0
@@ -1245,12 +1245,14 @@ static inline pmd_t *pmd_alloc(struct mm
 static inline void pgtable_page_ctor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_init(page);

include/linux/mm.h static inline pmd_t *pmd_alloc(struct mm · line 1257

Quoted 10 lines
include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +2 -0
+	inc_mm_counter(mm, MM_PTEPAGES);
 	inc_zone_page_state(page, NR_PAGETABLE);
 }
 
 static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page)
 {
 	pte_lock_deinit(page);
+	dec_mm_counter(mm, MM_PTEPAGES);
 	dec_zone_page_state(page, NR_PAGETABLE);
 }

I'm probably missing something really obvious but...

Is this safe in the non-USE_SPLIT_PTLOCKS case? If we're not using split-ptlocks then inc/dec_mm_counter() are only safe when done under mm->page_table_lock, right? But it looks to me like we can end up doing,

__pte_alloc()

      pte_alloc_one()
          pgtable_page_ctor()

before acquiring mm->page_table_lock in __pte_alloc().

Signature · 8 lines
Matt Fleming, Intel Open Source Technology Center

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#4 lore raw

Re: [RFC][PATCH 2/3] track numbers of pagetable pages

Quoted 13 lines · Matt Fleming

include/linux/mm.h static inline pmd_t *pmd_alloc(struct mm · line 1257

Quoted 6 lines

static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page) {

include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +1 -0
 	pte_lock_deinit(page);
+	dec_mm_counter(mm, MM_PTEPAGES);
 	dec_zone_page_state(page, NR_PAGETABLE);
 }

I'm probably missing something really obvious but...

Is this safe in the non-USE_SPLIT_PTLOCKS case? If we're not using split-ptlocks then inc/dec_mm_counter() are only safe when done under mm->page_table_lock, right? But it looks to me like we can end up doing,

Quoted 5 lines

__pte_alloc()

      pte_alloc_one()
          pgtable_page_ctor()

before acquiring mm->page_table_lock in __pte_alloc().

No, it's probably not safe. We'll have to come up with something a bit different in that case. Either that, or just kill the non-atomic case. Surely there's some percpu magic counter somewhere in the kernel that is optimized for fast (unlocked?) updates and rare, slow reads.

-- Dave

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw

Re: [RFC][PATCH 2/3] track numbers of pagetable pages

[Added Hugh Dickins to the CC list]

Sorry it's taken me so long to reply Dave.

Quoted 18 lines · On Mon, 18 Apr 2011 08:02:04 -0700 Dave Hansen <[email protected]> wrote:
Quoted 17 lines · Matt Fleming

include/linux/mm.h static inline pmd_t *pmd_alloc(struct mm · line 1257

Quoted 6 lines

static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page) {

include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +1 -0
 	pte_lock_deinit(page);
+	dec_mm_counter(mm, MM_PTEPAGES);
 	dec_zone_page_state(page, NR_PAGETABLE);
 }

I'm probably missing something really obvious but...

Is this safe in the non-USE_SPLIT_PTLOCKS case? If we're not using split-ptlocks then inc/dec_mm_counter() are only safe when done under mm->page_table_lock, right? But it looks to me like we can end up doing,

__pte_alloc()

      pte_alloc_one()
          pgtable_page_ctor()
Quoted 6 lines
Quoted 1 line

before acquiring mm->page_table_lock in __pte_alloc().

No, it's probably not safe. We'll have to come up with something a bit different in that case. Either that, or just kill the non-atomic case. Surely there's some percpu magic counter somewhere in the kernel that is optimized for fast (unlocked?) updates and rare, slow reads.

It seems it was Hugh that added these atomics in f412ac08c986 ("[PATCH]
mm: fix rss and mmlist locking").

Hugh, what was the reason that you left the old counters around (the ones protected by page_table_lock)? It seems to me that we could delete those and just have the single case that uses the atomic_t operations.

Would anyone object to a patch that removed the non-atomic case?

Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
#6 lore raw

Re: [RFC][PATCH 2/3] track numbers of pagetable pages

Quoted 32 lines · Matt Fleming

[Added Hugh Dickins to the CC list]

Sorry it's taken me so long to reply Dave.

Quoted 18 lines · On Mon, 18 Apr 2011 08:02:04 -0700 Dave Hansen <[email protected]> wrote:
Quoted 17 lines · Matt Fleming

include/linux/mm.h static inline pmd_t *pmd_alloc(struct mm · line 1257

Quoted 6 lines

static inline void pgtable_page_dtor(struct mm_struct *mm, struct page *page) {

include/linux/mm.h renamed from include/linux/mm.h~track-pagetable-pages +1 -0
 	pte_lock_deinit(page);
+	dec_mm_counter(mm, MM_PTEPAGES);
 	dec_zone_page_state(page, NR_PAGETABLE);
 }

I'm probably missing something really obvious but...

Is this safe in the non-USE_SPLIT_PTLOCKS case? If we're not using split-ptlocks then inc/dec_mm_counter() are only safe when done under mm->page_table_lock, right? But it looks to me like we can end up doing,

__pte_alloc()

      pte_alloc_one()
          pgtable_page_ctor()
Quoted 6 lines
Quoted 1 line

before acquiring mm->page_table_lock in __pte_alloc().

No, it's probably not safe. We'll have to come up with something a bit different in that case. Either that, or just kill the non-atomic case. Surely there's some percpu magic counter somewhere in the kernel that is optimized for fast (unlocked?) updates and rare, slow reads.

Quoted 7 lines

It seems it was Hugh that added these atomics in f412ac08c986 ("[PATCH]
mm: fix rss and mmlist locking").

Hugh, what was the reason that you left the old counters around (the ones protected by page_table_lock)? It seems to me that we could delete those and just have the single case that uses the atomic_t operations.

The only reason was to avoid adding costly atomic operations into a configuration that had no need for them there: the page_table_lock sufficed.

Certainly it would be simpler just to delete the non-atomic variant.

And I think it's fair to say that any configuration on which we're measuring performance to that degree (rather than "does it boot fast?" type measurements), would already be going the split ptlocks route.

Quoted 2 lines

Would anyone object to a patch that removed the non-atomic case?

Not I.

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw

RFC PATCH 3/3 use pte pages in OOM score

In reply to Dave Hansen

PTE pages eat up memory just like anything else, but we do not account for them in any way in the OOM scores. They are also _guaranteed_ to get freed up when a process is OOM killed, while RSS is not.

---

 linux-2.6.git-dave/mm/oom_kill.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
mm/oom_kill.c renamed from mm/oom_kill.c~use-pte-pages-in-oom-scire +4 -2
diff -puN mm/oom_kill.c~use-pte-pages-in-oom-scire mm/oom_kill.c
@@ -192,8 +192,10 @@ unsigned int oom_badness(struct task_str
 	 * The baseline for the badness score is the proportion of RAM that each
 	 * task's rss and swap space use.
 	 */
-	points = (get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS)) * 1000 /
-			totalpages;
+	points = (get_mm_rss(p->mm) +
+		  get_mm_counter(p->mm, MM_SWAPENTS) +
+		  get_mm_counter(p->mm, MM_PTEPAGES))
+		 * 1000 / totalpages;
 	task_unlock(p);
 
 	/*

_

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>