diff mbox

[2/2] sparc64: Fix pagetable freeing for hugepage regions

Message ID 1466644374-58354-2-git-send-email-nitin.m.gupta@oracle.com
State Superseded
Delegated to: David Miller
Headers show

Commit Message

Nitin Gupta June 23, 2016, 1:11 a.m. UTC
8M pages now allocate page tables till PMD level only.
So, when freeing page table for 8M hugepage backed region,
make sure we don't try to access non-existent PTE level.

Signed-off-by: Nitin Gupta <nitin.m.gupta@oracle.com>
---
 arch/sparc/include/asm/hugetlb.h |  8 ----
 arch/sparc/mm/hugetlbpage.c      | 98 ++++++++++++++++++++++++++++++++++++++++
 include/linux/hugetlb.h          |  4 ++
 3 files changed, 102 insertions(+), 8 deletions(-)

Comments

kernel test robot June 23, 2016, 2:38 a.m. UTC | #1
Hi,

[auto build test ERROR on sparc/master]
[also build test ERROR on v4.7-rc4 next-20160622]
[cannot apply to sparc-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nitin-Gupta/sparc64-Trim-page-tables-for-8M-hugepages/20160623-092926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git master
config: i386-defconfig (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from include/linux/hugetlb.h:420:0,
                    from kernel/fork.c:38:
>> arch/x86/include/asm/hugetlb.h:30:20: error: static declaration of 'hugetlb_free_pgd_range' follows non-static declaration
    static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
                       ^~~~~~~~~~~~~~~~~~~~~~
   In file included from kernel/fork.c:38:0:
   include/linux/hugetlb.h:123:6: note: previous declaration of 'hugetlb_free_pgd_range' was here
    void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
         ^~~~~~~~~~~~~~~~~~~~~~

vim +/hugetlb_free_pgd_range +30 arch/x86/include/asm/hugetlb.h

6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  24  		return -EINVAL;
a5516438 include/asm-x86/hugetlb.h Andi Kleen      2008-07-23  25  	if (addr & ~huge_page_mask(h))
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  26  		return -EINVAL;
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  27  	return 0;
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  28  }
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  29  
42b77728 include/asm-x86/hugetlb.h Jan Beulich     2008-07-23 @30  static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  31  					  unsigned long addr, unsigned long end,
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  32  					  unsigned long floor,
6d779079 include/asm-x86/hugetlb.h Gerald Schaefer 2008-04-28  33  					  unsigned long ceiling)

:::::: The code at line 30 was first introduced by commit
:::::: 42b7772812d15b86543a23b82bd6070eef9a08b1 mm: remove double indirection on tlb parameter to free_pgd_range() & Co

:::::: TO: Jan Beulich <jbeulich@novell.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot June 23, 2016, 3:27 a.m. UTC | #2
Hi,

[auto build test ERROR on sparc/master]
[also build test ERROR on v4.7-rc4 next-20160622]
[cannot apply to sparc-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nitin-Gupta/sparc64-Trim-page-tables-for-8M-hugepages/20160623-092926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git master
config: sh-sh7785lcr_32bit_defconfig (attached as .config)
compiler: sh4-linux-gnu-gcc (Debian 5.3.1-8) 5.3.1 20160205
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sh 

All errors (new ones prefixed by >>):

   In file included from include/linux/hugetlb.h:420:0,
                    from fs/hugetlbfs/inode.c:28:
>> arch/sh/include/asm/hugetlb.h:29:20: error: static declaration of 'hugetlb_free_pgd_range' follows non-static declaration
    static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
                       ^
   In file included from fs/hugetlbfs/inode.c:28:0:
   include/linux/hugetlb.h:123:6: note: previous declaration of 'hugetlb_free_pgd_range' was here
    void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
         ^

vim +/hugetlb_free_pgd_range +29 arch/sh/include/asm/hugetlb.h

6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  23  		return -EINVAL;
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  24  	if (addr & ~HPAGE_MASK)
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  25  		return -EINVAL;
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  26  	return 0;
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  27  }
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  28  
42b77728 include/asm-sh/hugetlb.h Jan Beulich     2008-07-23 @29  static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  30  					  unsigned long addr, unsigned long end,
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  31  					  unsigned long floor,
6d779079 include/asm-sh/hugetlb.h Gerald Schaefer 2008-04-28  32  					  unsigned long ceiling)

:::::: The code at line 29 was first introduced by commit
:::::: 42b7772812d15b86543a23b82bd6070eef9a08b1 mm: remove double indirection on tlb parameter to free_pgd_range() & Co

:::::: TO: Jan Beulich <jbeulich@novell.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot June 23, 2016, 3:30 a.m. UTC | #3
Hi,

[auto build test ERROR on sparc/master]
[also build test ERROR on v4.7-rc4 next-20160622]
[cannot apply to sparc-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nitin-Gupta/sparc64-Trim-page-tables-for-8M-hugepages/20160623-092926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git master
config: tile-tilegx_defconfig (attached as .config)
compiler: tilegx-linux-gcc (GCC) 4.6.2
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=tile 

All errors (new ones prefixed by >>):

   In file included from include/linux/hugetlb.h:420:0,
                    from arch/tile/kernel/proc.c:25:
>> arch/tile/include/asm/hugetlb.h:43:20: error: static declaration of 'hugetlb_free_pgd_range' follows non-static declaration
   include/linux/hugetlb.h:123:6: note: previous declaration of 'hugetlb_free_pgd_range' was here

vim +/hugetlb_free_pgd_range +43 arch/tile/include/asm/hugetlb.h

867e359b Chris Metcalf 2010-05-28  37  		return -EINVAL;
867e359b Chris Metcalf 2010-05-28  38  	if (addr & ~huge_page_mask(h))
867e359b Chris Metcalf 2010-05-28  39  		return -EINVAL;
867e359b Chris Metcalf 2010-05-28  40  	return 0;
867e359b Chris Metcalf 2010-05-28  41  }
867e359b Chris Metcalf 2010-05-28  42  
867e359b Chris Metcalf 2010-05-28 @43  static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
867e359b Chris Metcalf 2010-05-28  44  					  unsigned long addr, unsigned long end,
867e359b Chris Metcalf 2010-05-28  45  					  unsigned long floor,
867e359b Chris Metcalf 2010-05-28  46  					  unsigned long ceiling)

:::::: The code at line 43 was first introduced by commit
:::::: 867e359b97c970a60626d5d76bbe2a8fadbf38fb arch/tile: core support for Tilera 32-bit chips.

:::::: TO: Chris Metcalf <cmetcalf@tilera.com>
:::::: CC: Chris Metcalf <cmetcalf@tilera.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index 139e711..1a6708c 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -31,14 +31,6 @@  static inline int prepare_hugepage_range(struct file *file,
 	return 0;
 }
 
-static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
-					  unsigned long addr, unsigned long end,
-					  unsigned long floor,
-					  unsigned long ceiling)
-{
-	free_pgd_range(tlb, addr, end, floor, ceiling);
-}
-
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long addr, pte_t *ptep)
 {
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index cafb5ca..494c390 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -12,6 +12,7 @@ 
 
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
@@ -202,3 +203,100 @@  int pud_huge(pud_t pud)
 {
 	return 0;
 }
+
+static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
+			   unsigned long addr)
+{
+	pgtable_t token = pmd_pgtable(*pmd);
+
+	pmd_clear(pmd);
+	pte_free_tlb(tlb, token, addr);
+	atomic_long_dec(&tlb->mm->nr_ptes);
+}
+
+static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+				   unsigned long addr, unsigned long end,
+				   unsigned long floor, unsigned long ceiling)
+{
+	pmd_t *pmd;
+	unsigned long next;
+	unsigned long start;
+
+	start = addr;
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		if (pmd_none(*pmd))
+			continue;
+		if (is_hugetlb_pmd(*pmd))
+			pmd_clear(pmd);
+		else
+			hugetlb_free_pte_range(tlb, pmd, addr);
+	} while (pmd++, addr = next, addr != end);
+
+	start &= PUD_MASK;
+	if (start < floor)
+		return;
+	if (ceiling) {
+		ceiling &= PUD_MASK;
+		if (!ceiling)
+			return;
+	}
+	if (end - 1 > ceiling - 1)
+		return;
+
+	pmd = pmd_offset(pud, start);
+	pud_clear(pud);
+	pmd_free_tlb(tlb, pmd, start);
+	mm_dec_nr_pmds(tlb->mm);
+}
+
+static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+				   unsigned long addr, unsigned long end,
+				   unsigned long floor, unsigned long ceiling)
+{
+	pud_t *pud;
+	unsigned long next;
+	unsigned long start;
+
+	start = addr;
+	pud = pud_offset(pgd, addr);
+	do {
+		next = pud_addr_end(addr, end);
+		if (pud_none_or_clear_bad(pud))
+			continue;
+		hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
+				       ceiling);
+	} while (pud++, addr = next, addr != end);
+
+	start &= PGDIR_MASK;
+	if (start < floor)
+		return;
+	if (ceiling) {
+		ceiling &= PGDIR_MASK;
+		if (!ceiling)
+			return;
+	}
+	if (end - 1 > ceiling - 1)
+		return;
+
+	pud = pud_offset(pgd, start);
+	pgd_clear(pgd);
+	pud_free_tlb(tlb, pud, start);
+}
+
+void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+			    unsigned long addr, unsigned long end,
+			    unsigned long floor, unsigned long ceiling)
+{
+	pgd_t *pgd;
+	unsigned long next;
+
+	pgd = pgd_offset(tlb->mm, addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		if (pgd_none_or_clear_bad(pgd))
+			continue;
+		hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
+	} while (pgd++, addr = next, addr != end);
+}
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index c26d463..4461309 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -120,6 +120,10 @@  int pud_huge(pud_t pmd);
 unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 		unsigned long address, unsigned long end, pgprot_t newprot);
 
+void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
+			    unsigned long end, unsigned long floor,
+			    unsigned long ceiling);
+
 #else /* !CONFIG_HUGETLB_PAGE */
 
 static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma)