All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] powerpc/mm: update ptep_set_access_flag to not do full mm tlb flush
@ 2016-11-10  9:29 ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

When we are updating pte, we just need to flush the tlb mapping for
that pte. Right now we do a full mm flush because we don't track page
size. Update the interface to track the page size and use that to
do the right tlb flush.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/32/pgtable.h |  4 +++-
 arch/powerpc/include/asm/book3s/64/pgtable.h |  7 +++++--
 arch/powerpc/include/asm/book3s/64/radix.h   | 14 +++++++-------
 arch/powerpc/include/asm/nohash/32/pgtable.h |  4 +++-
 arch/powerpc/include/asm/nohash/64/pgtable.h |  4 +++-
 arch/powerpc/mm/pgtable-book3s64.c           |  3 ++-
 arch/powerpc/mm/pgtable-radix.c              | 16 ++++++++++++++++
 arch/powerpc/mm/pgtable.c                    | 10 ++++++++--
 arch/powerpc/mm/tlb-radix.c                  | 15 ---------------
 9 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 6b8b2d57fdc8..0713626e9189 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -224,7 +224,9 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 86870c11917b..46d739457d68 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -580,10 +580,13 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev)
  */
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	if (radix_enabled())
-		return radix__ptep_set_access_flags(mm, ptep, entry);
+		return radix__ptep_set_access_flags(mm, ptep, entry,
+						    address, pg_sz);
 	return hash__ptep_set_access_flags(ptep, entry);
 }
 
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 2a46dea8e1b1..279b2f68e00f 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -110,6 +110,7 @@
 #define RADIX_PUD_TABLE_SIZE	(sizeof(pud_t) << RADIX_PUD_INDEX_SIZE)
 #define RADIX_PGD_TABLE_SIZE	(sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE)
 
+extern int radix_get_mmu_psize(unsigned long pg_sz);
 static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
 					       unsigned long set)
 {
@@ -167,7 +168,9 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
  * function doesn't need to invalidate tlb.
  */
 static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
-						pte_t *ptep, pte_t entry)
+						pte_t *ptep, pte_t entry,
+						unsigned long address,
+						unsigned long pg_sz)
 {
 
 	unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
@@ -175,6 +178,7 @@ static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
 
 	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
 
+		int psize;
 		unsigned long old_pte, new_pte;
 
 		old_pte = __radix_pte_update(ptep, ~0, 0);
@@ -183,12 +187,8 @@ static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
 		 * new value of pte
 		 */
 		new_pte = old_pte | set;
-
-		/*
-		 * For now let's do heavy pid flush
-		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
-		 */
-		radix__flush_tlb_mm(mm);
+		psize = radix_get_mmu_psize(pg_sz);
+		radix__flush_tlb_page_psize(mm, address, psize);
 
 		__radix_pte_update(ptep, 0, new_pte);
 	} else
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index c219ef7be53b..24ee66bf7223 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -268,7 +268,9 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 653a1838469d..86d49dc60ec6 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -301,7 +301,9 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
  * function doesn't need to flush the hash entry
  */
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long bits = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index f4f437cbabf1..5c7c501b7cae 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -35,7 +35,8 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 #endif
 	changed = !pmd_same(*(pmdp), entry);
 	if (changed) {
-		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry));
+		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry),
+					address, HPAGE_PMD_SIZE);
 		flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	}
 	return changed;
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index ed7bddc456b7..6b1ffc449158 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -222,6 +222,22 @@ static int __init get_idx_from_shift(unsigned int shift)
 	return idx;
 }
 
+int radix_get_mmu_psize(unsigned long page_size)
+{
+	int psize;
+
+	if (page_size == (1UL << mmu_psize_defs[mmu_virtual_psize].shift))
+		psize = mmu_virtual_psize;
+	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_2M].shift))
+		psize = MMU_PAGE_2M;
+	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_1G].shift))
+		psize = MMU_PAGE_1G;
+	else
+		return -1;
+	return psize;
+}
+
+
 static int __init radix_dt_scan_page_sizes(unsigned long node,
 					   const char *uname, int depth,
 					   void *data)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 911fdfb63ec1..a9ec0d8f1bcf 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -219,12 +219,18 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 			  pte_t *ptep, pte_t entry, int dirty)
 {
 	int changed;
+	unsigned long pg_sz;
+
 	entry = set_access_flags_filter(entry, vma, dirty);
 	changed = !pte_same(*(ptep), entry);
 	if (changed) {
-		if (!is_vm_hugetlb_page(vma))
+		if (!is_vm_hugetlb_page(vma)) {
+			pg_sz = PAGE_SIZE;
 			assert_pte_locked(vma->vm_mm, address);
-		__ptep_set_access_flags(vma->vm_mm, ptep, entry);
+		} else
+			pg_sz = huge_page_size(hstate_vma(vma));
+		__ptep_set_access_flags(vma->vm_mm, ptep, entry,
+					address, pg_sz);
 		flush_tlb_page(vma, address);
 	}
 	return changed;
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 0e49ec541ab5..0b923c37cd30 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -278,21 +278,6 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 }
 EXPORT_SYMBOL(radix__flush_tlb_range);
 
-static int radix_get_mmu_psize(int page_size)
-{
-	int psize;
-
-	if (page_size == (1UL << mmu_psize_defs[mmu_virtual_psize].shift))
-		psize = mmu_virtual_psize;
-	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_2M].shift))
-		psize = MMU_PAGE_2M;
-	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_1G].shift))
-		psize = MMU_PAGE_1G;
-	else
-		return -1;
-	return psize;
-}
-
 void radix__tlb_flush(struct mmu_gather *tlb)
 {
 	int psize = 0;
-- 
2.10.2

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 1/4] powerpc/mm: update ptep_set_access_flag to not do full mm tlb flush
@ 2016-11-10  9:29 ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

When we are updating pte, we just need to flush the tlb mapping for
that pte. Right now we do a full mm flush because we don't track page
size. Update the interface to track the page size and use that to
do the right tlb flush.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/32/pgtable.h |  4 +++-
 arch/powerpc/include/asm/book3s/64/pgtable.h |  7 +++++--
 arch/powerpc/include/asm/book3s/64/radix.h   | 14 +++++++-------
 arch/powerpc/include/asm/nohash/32/pgtable.h |  4 +++-
 arch/powerpc/include/asm/nohash/64/pgtable.h |  4 +++-
 arch/powerpc/mm/pgtable-book3s64.c           |  3 ++-
 arch/powerpc/mm/pgtable-radix.c              | 16 ++++++++++++++++
 arch/powerpc/mm/pgtable.c                    | 10 ++++++++--
 arch/powerpc/mm/tlb-radix.c                  | 15 ---------------
 9 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 6b8b2d57fdc8..0713626e9189 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -224,7 +224,9 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 86870c11917b..46d739457d68 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -580,10 +580,13 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev)
  */
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	if (radix_enabled())
-		return radix__ptep_set_access_flags(mm, ptep, entry);
+		return radix__ptep_set_access_flags(mm, ptep, entry,
+						    address, pg_sz);
 	return hash__ptep_set_access_flags(ptep, entry);
 }
 
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 2a46dea8e1b1..279b2f68e00f 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -110,6 +110,7 @@
 #define RADIX_PUD_TABLE_SIZE	(sizeof(pud_t) << RADIX_PUD_INDEX_SIZE)
 #define RADIX_PGD_TABLE_SIZE	(sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE)
 
+extern int radix_get_mmu_psize(unsigned long pg_sz);
 static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
 					       unsigned long set)
 {
@@ -167,7 +168,9 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
  * function doesn't need to invalidate tlb.
  */
 static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
-						pte_t *ptep, pte_t entry)
+						pte_t *ptep, pte_t entry,
+						unsigned long address,
+						unsigned long pg_sz)
 {
 
 	unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
@@ -175,6 +178,7 @@ static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
 
 	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
 
+		int psize;
 		unsigned long old_pte, new_pte;
 
 		old_pte = __radix_pte_update(ptep, ~0, 0);
@@ -183,12 +187,8 @@ static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
 		 * new value of pte
 		 */
 		new_pte = old_pte | set;
-
-		/*
-		 * For now let's do heavy pid flush
-		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
-		 */
-		radix__flush_tlb_mm(mm);
+		psize = radix_get_mmu_psize(pg_sz);
+		radix__flush_tlb_page_psize(mm, address, psize);
 
 		__radix_pte_update(ptep, 0, new_pte);
 	} else
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index c219ef7be53b..24ee66bf7223 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -268,7 +268,9 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 
 
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 653a1838469d..86d49dc60ec6 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -301,7 +301,9 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
  * function doesn't need to flush the hash entry
  */
 static inline void __ptep_set_access_flags(struct mm_struct *mm,
-					   pte_t *ptep, pte_t entry)
+					   pte_t *ptep, pte_t entry,
+					   unsigned long address,
+					   unsigned long pg_sz)
 {
 	unsigned long bits = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index f4f437cbabf1..5c7c501b7cae 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -35,7 +35,8 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 #endif
 	changed = !pmd_same(*(pmdp), entry);
 	if (changed) {
-		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry));
+		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry),
+					address, HPAGE_PMD_SIZE);
 		flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	}
 	return changed;
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index ed7bddc456b7..6b1ffc449158 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -222,6 +222,22 @@ static int __init get_idx_from_shift(unsigned int shift)
 	return idx;
 }
 
+int radix_get_mmu_psize(unsigned long page_size)
+{
+	int psize;
+
+	if (page_size == (1UL << mmu_psize_defs[mmu_virtual_psize].shift))
+		psize = mmu_virtual_psize;
+	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_2M].shift))
+		psize = MMU_PAGE_2M;
+	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_1G].shift))
+		psize = MMU_PAGE_1G;
+	else
+		return -1;
+	return psize;
+}
+
+
 static int __init radix_dt_scan_page_sizes(unsigned long node,
 					   const char *uname, int depth,
 					   void *data)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 911fdfb63ec1..a9ec0d8f1bcf 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -219,12 +219,18 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 			  pte_t *ptep, pte_t entry, int dirty)
 {
 	int changed;
+	unsigned long pg_sz;
+
 	entry = set_access_flags_filter(entry, vma, dirty);
 	changed = !pte_same(*(ptep), entry);
 	if (changed) {
-		if (!is_vm_hugetlb_page(vma))
+		if (!is_vm_hugetlb_page(vma)) {
+			pg_sz = PAGE_SIZE;
 			assert_pte_locked(vma->vm_mm, address);
-		__ptep_set_access_flags(vma->vm_mm, ptep, entry);
+		} else
+			pg_sz = huge_page_size(hstate_vma(vma));
+		__ptep_set_access_flags(vma->vm_mm, ptep, entry,
+					address, pg_sz);
 		flush_tlb_page(vma, address);
 	}
 	return changed;
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 0e49ec541ab5..0b923c37cd30 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -278,21 +278,6 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 }
 EXPORT_SYMBOL(radix__flush_tlb_range);
 
-static int radix_get_mmu_psize(int page_size)
-{
-	int psize;
-
-	if (page_size == (1UL << mmu_psize_defs[mmu_virtual_psize].shift))
-		psize = mmu_virtual_psize;
-	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_2M].shift))
-		psize = MMU_PAGE_2M;
-	else if (page_size == (1UL << mmu_psize_defs[MMU_PAGE_1G].shift))
-		psize = MMU_PAGE_1G;
-	else
-		return -1;
-	return psize;
-}
-
 void radix__tlb_flush(struct mmu_gather *tlb)
 {
 	int psize = 0;
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] powerpc/mm: Rename hugetlb-radix.h to hugetlb.h
  2016-11-10  9:29 ` Aneesh Kumar K.V
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  -1 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

We will start moving some book3s specific hugetlb functions there.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/64/{hugetlb-radix.h => hugetlb.h} | 6 ++++--
 arch/powerpc/include/asm/hugetlb.h                                | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)
 rename arch/powerpc/include/asm/book3s/64/{hugetlb-radix.h => hugetlb.h} (84%)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb-radix.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
similarity index 84%
rename from arch/powerpc/include/asm/book3s/64/hugetlb-radix.h
rename to arch/powerpc/include/asm/book3s/64/hugetlb.h
index c45189aa7476..a7d2b6107383 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb-radix.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_RADIX_H
-#define _ASM_POWERPC_BOOK3S_64_HUGETLB_RADIX_H
+#ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_H
+#define _ASM_POWERPC_BOOK3S_64_HUGETLB_H
 /*
  * For radix we want generic code to handle hugetlb. But then if we want
  * both hash and radix to be enabled together we need to workaround the
@@ -21,6 +21,8 @@ static inline int hstate_get_psize(struct hstate *hstate)
 		return MMU_PAGE_2M;
 	else if (shift == mmu_psize_defs[MMU_PAGE_1G].shift)
 		return MMU_PAGE_1G;
+	else if (shift == mmu_psize_defs[MMU_PAGE_16M].shift)
+		return MMU_PAGE_16M;
 	else {
 		WARN(1, "Wrong huge page shift\n");
 		return mmu_virtual_psize;
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index c5517f463ec7..c03e0a3dd4d8 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -9,7 +9,7 @@ extern struct kmem_cache *hugepte_cache;
 
 #ifdef CONFIG_PPC_BOOK3S_64
 
-#include <asm/book3s/64/hugetlb-radix.h>
+#include <asm/book3s/64/hugetlb.h>
 /*
  * This should work for other subarchs too. But right now we use the
  * new format only for 64bit book3s
-- 
2.10.2

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] powerpc/mm: Rename hugetlb-radix.h to hugetlb.h
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

We will start moving some book3s specific hugetlb functions there.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/64/{hugetlb-radix.h => hugetlb.h} | 6 ++++--
 arch/powerpc/include/asm/hugetlb.h                                | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)
 rename arch/powerpc/include/asm/book3s/64/{hugetlb-radix.h => hugetlb.h} (84%)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb-radix.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
similarity index 84%
rename from arch/powerpc/include/asm/book3s/64/hugetlb-radix.h
rename to arch/powerpc/include/asm/book3s/64/hugetlb.h
index c45189aa7476..a7d2b6107383 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb-radix.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_RADIX_H
-#define _ASM_POWERPC_BOOK3S_64_HUGETLB_RADIX_H
+#ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_H
+#define _ASM_POWERPC_BOOK3S_64_HUGETLB_H
 /*
  * For radix we want generic code to handle hugetlb. But then if we want
  * both hash and radix to be enabled together we need to workaround the
@@ -21,6 +21,8 @@ static inline int hstate_get_psize(struct hstate *hstate)
 		return MMU_PAGE_2M;
 	else if (shift == mmu_psize_defs[MMU_PAGE_1G].shift)
 		return MMU_PAGE_1G;
+	else if (shift == mmu_psize_defs[MMU_PAGE_16M].shift)
+		return MMU_PAGE_16M;
 	else {
 		WARN(1, "Wrong huge page shift\n");
 		return mmu_virtual_psize;
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index c5517f463ec7..c03e0a3dd4d8 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -9,7 +9,7 @@ extern struct kmem_cache *hugepte_cache;
 
 #ifdef CONFIG_PPC_BOOK3S_64
 
-#include <asm/book3s/64/hugetlb-radix.h>
+#include <asm/book3s/64/hugetlb.h>
 /*
  * This should work for other subarchs too. But right now we use the
  * new format only for 64bit book3s
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
  2016-11-10  9:29 ` Aneesh Kumar K.V
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  -1 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

This help us to find the hugetlb page size which we need ot use on some
archs like ppc64 for tlbflush. This also make the interface consistent
with other hugetlb functions

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/arm/include/asm/hugetlb-3level.h        |  8 ++++----
 arch/arm64/include/asm/hugetlb.h             |  4 ++--
 arch/arm64/mm/hugetlbpage.c                  |  7 +++++--
 arch/ia64/include/asm/hugetlb.h              |  8 ++++----
 arch/metag/include/asm/hugetlb.h             |  8 ++++----
 arch/mips/include/asm/hugetlb.h              |  7 ++++---
 arch/parisc/include/asm/hugetlb.h            |  4 ++--
 arch/parisc/mm/hugetlbpage.c                 |  6 ++++--
 arch/powerpc/include/asm/book3s/32/pgtable.h |  4 ++--
 arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
 arch/powerpc/include/asm/book3s/64/pgtable.h |  9 ---------
 arch/powerpc/include/asm/hugetlb.h           |  6 +++---
 arch/powerpc/include/asm/nohash/32/pgtable.h |  4 ++--
 arch/powerpc/include/asm/nohash/64/pgtable.h |  4 ++--
 arch/s390/include/asm/hugetlb.h              | 12 ++++++------
 arch/s390/mm/hugetlbpage.c                   |  3 ++-
 arch/sh/include/asm/hugetlb.h                |  8 ++++----
 arch/sparc/include/asm/hugetlb.h             |  6 +++---
 arch/sparc/mm/hugetlbpage.c                  |  3 ++-
 arch/tile/include/asm/hugetlb.h              |  8 ++++----
 arch/x86/include/asm/hugetlb.h               |  8 ++++----
 mm/hugetlb.c                                 |  6 +++---
 22 files changed, 76 insertions(+), 67 deletions(-)

diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
index d4014fbe5ea3..b71839e1786f 100644
--- a/arch/arm/include/asm/hugetlb-3level.h
+++ b/arch/arm/include/asm/hugetlb-3level.h
@@ -49,16 +49,16 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 	ptep_clear_flush(vma, addr, ptep);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index bbc1e35aa601..4e54d4b58d3e 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -76,9 +76,9 @@ extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 				      unsigned long addr, pte_t *ptep,
 				      pte_t pte, int dirty);
-extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+extern pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 				     unsigned long addr, pte_t *ptep);
-extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
+extern void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 				    unsigned long addr, pte_t *ptep);
 extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
 				  unsigned long addr, pte_t *ptep);
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 2e49bd252fe7..5c8903433cd9 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -197,10 +197,11 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 	return entry;
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep)
 {
 	pte_t pte;
+	struct mm_struct *mm = vma->vm_mm;
 
 	if (pte_cont(*ptep)) {
 		int ncontig, i;
@@ -263,9 +264,11 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 	}
 }
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 			     unsigned long addr, pte_t *ptep)
 {
+	struct mm_struct *mm = vma->vm_mm;
+
 	if (pte_cont(*ptep)) {
 		int ncontig, i;
 		pte_t *cpte;
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
index ef65f026b11e..eb1c1d674200 100644
--- a/arch/ia64/include/asm/hugetlb.h
+++ b/arch/ia64/include/asm/hugetlb.h
@@ -26,10 +26,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -47,10 +47,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h
index 905ed422dbeb..310b103127a6 100644
--- a/arch/metag/include/asm/hugetlb.h
+++ b/arch/metag/include/asm/hugetlb.h
@@ -28,10 +28,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -49,10 +49,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index 982bc0685330..4380acbff8e2 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -53,11 +53,12 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 	pte_t clear;
 	pte_t pte = *ptep;
+	struct mm_struct *mm = vma->vm_mm;
 
 	pte_val(clear) = (unsigned long)invalid_pte_table;
 	set_pte_at(mm, addr, ptep, clear);
@@ -81,10 +82,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
index a65d888716c4..3a6070842016 100644
--- a/arch/parisc/include/asm/hugetlb.h
+++ b/arch/parisc/include/asm/hugetlb.h
@@ -8,7 +8,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep);
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
@@ -54,7 +54,7 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep);
 
 int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index 5d6eea925cf4..e01fd08ed72c 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -142,11 +142,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 }
 
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep)
 {
 	unsigned long flags;
 	pte_t entry;
+	struct mm_struct *mm = vma->vma_mm;
 
 	purge_tlb_start(flags);
 	entry = *ptep;
@@ -157,11 +158,12 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 }
 
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep)
 {
 	unsigned long flags;
 	pte_t old_pte;
+	struct mm_struct *mm = vma->vm_mm;
 
 	purge_tlb_start(flags);
 	old_pte = *ptep;
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 0713626e9189..34c8fd0c5d04 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -216,10 +216,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 {
 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
 }
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 
diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index a7d2b6107383..58e00dbbf15c 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -28,4 +28,14 @@ static inline int hstate_get_psize(struct hstate *hstate)
 		return mmu_virtual_psize;
 	}
 }
+
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
+					   unsigned long addr, pte_t *ptep)
+{
+	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
+		return;
+
+	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
+}
+
 #endif
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 46d739457d68..ef2eef1ba99a 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -346,15 +346,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
-					   unsigned long addr, pte_t *ptep)
-{
-	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
-		return;
-
-	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
-}
-
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pte_t *ptep)
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index c03e0a3dd4d8..b152e0c8dc4e 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -132,11 +132,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 #ifdef CONFIG_PPC64
-	return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
+	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
 #else
 	return __pte(pte_update(ptep, ~0UL, 0));
 #endif
@@ -146,7 +146,7 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long addr, pte_t *ptep)
 {
 	pte_t pte;
-	pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+	pte = huge_ptep_get_and_clear(vma, addr, ptep);
 	flush_hugetlb_page(vma, addr);
 }
 
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 24ee66bf7223..db83c15f1d54 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -260,10 +260,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 {
 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
 }
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 86d49dc60ec6..16c77d923209 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -257,13 +257,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	if ((pte_val(*ptep) & _PAGE_RW) == 0)
 		return;
 
-	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
+	pte_update(vma->vm_mm, addr, ptep, _PAGE_RW, 0, 1);
 }
 
 /*
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 4c7fac75090e..eb411d59ab77 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -19,7 +19,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 pte_t huge_ptep_get(pte_t *ptep);
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep);
 
 /*
@@ -50,7 +50,7 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long address, pte_t *ptep)
 {
-	huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
+	huge_ptep_get_and_clear(vma, address, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
@@ -59,17 +59,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 {
 	int changed = !pte_same(huge_ptep_get(ptep), pte);
 	if (changed) {
-		huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+		huge_ptep_get_and_clear(vma, addr, ptep);
 		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 	}
 	return changed;
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep);
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
+	pte_t pte = huge_ptep_get_and_clear(vma, addr, ptep);
+	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(pte));
 }
 
 static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index cd404aa3931c..61146137b0d2 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -136,12 +136,13 @@ pte_t huge_ptep_get(pte_t *ptep)
 	return __rste_to_pte(pte_val(*ptep));
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep)
 {
 	pte_t pte = huge_ptep_get(ptep);
 	pmd_t *pmdp = (pmd_t *) ptep;
 	pud_t *pudp = (pud_t *) ptep;
+	struct mm_struct *mm = vma->vm_mm;
 
 	if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
 		pudp_xchg_direct(mm, addr, pudp, __pud(_REGION3_ENTRY_EMPTY));
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index ef489a56fcce..925cbc0b4da9 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -40,10 +40,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -61,10 +61,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index dcbf985ab243..c7c21738b46c 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -8,7 +8,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep);
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
@@ -46,11 +46,11 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	pte_t old_pte = *ptep;
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(old_pte));
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 988acc8b1b80..c5d1fb4a83a7 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -174,10 +174,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, orig, 0);
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep)
 {
 	pte_t entry;
+	struct mm_struct *mm = vma->vm_mm;
 
 	entry = *ptep;
 	if (pte_present(entry))
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index 2fac5be4de26..aab3ff1cdb10 100644
--- a/arch/tile/include/asm/hugetlb.h
+++ b/arch/tile/include/asm/hugetlb.h
@@ -54,10 +54,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte(ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -76,10 +76,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
index 3a106165e03a..47b7a102a6a2 100644
--- a/arch/x86/include/asm/hugetlb.h
+++ b/arch/x86/include/asm/hugetlb.h
@@ -41,10 +41,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -63,10 +63,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ec49d9ef1eef..6b140f213e33 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3182,7 +3182,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			set_huge_pte_at(dst, addr, dst_pte, entry);
 		} else {
 			if (cow) {
-				huge_ptep_set_wrprotect(src, addr, src_pte);
+				huge_ptep_set_wrprotect(vma, addr, src_pte);
 				mmu_notifier_invalidate_range(src, mmun_start,
 								   mmun_end);
 			}
@@ -3271,7 +3271,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 			set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED);
 		}
 
-		pte = huge_ptep_get_and_clear(mm, address, ptep);
+		pte = huge_ptep_get_and_clear(vma, address, ptep);
 		tlb_remove_tlb_entry(tlb, ptep, address);
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
@@ -4020,7 +4020,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 			continue;
 		}
 		if (!huge_pte_none(pte)) {
-			pte = huge_ptep_get_and_clear(mm, address, ptep);
+			pte = huge_ptep_get_and_clear(vma, address, ptep);
 			pte = pte_mkhuge(huge_pte_modify(pte, newprot));
 			pte = arch_make_huge_pte(pte, vma, NULL, 0);
 			set_huge_pte_at(mm, address, ptep, pte);
-- 
2.10.2

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

This help us to find the hugetlb page size which we need ot use on some
archs like ppc64 for tlbflush. This also make the interface consistent
with other hugetlb functions

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/arm/include/asm/hugetlb-3level.h        |  8 ++++----
 arch/arm64/include/asm/hugetlb.h             |  4 ++--
 arch/arm64/mm/hugetlbpage.c                  |  7 +++++--
 arch/ia64/include/asm/hugetlb.h              |  8 ++++----
 arch/metag/include/asm/hugetlb.h             |  8 ++++----
 arch/mips/include/asm/hugetlb.h              |  7 ++++---
 arch/parisc/include/asm/hugetlb.h            |  4 ++--
 arch/parisc/mm/hugetlbpage.c                 |  6 ++++--
 arch/powerpc/include/asm/book3s/32/pgtable.h |  4 ++--
 arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
 arch/powerpc/include/asm/book3s/64/pgtable.h |  9 ---------
 arch/powerpc/include/asm/hugetlb.h           |  6 +++---
 arch/powerpc/include/asm/nohash/32/pgtable.h |  4 ++--
 arch/powerpc/include/asm/nohash/64/pgtable.h |  4 ++--
 arch/s390/include/asm/hugetlb.h              | 12 ++++++------
 arch/s390/mm/hugetlbpage.c                   |  3 ++-
 arch/sh/include/asm/hugetlb.h                |  8 ++++----
 arch/sparc/include/asm/hugetlb.h             |  6 +++---
 arch/sparc/mm/hugetlbpage.c                  |  3 ++-
 arch/tile/include/asm/hugetlb.h              |  8 ++++----
 arch/x86/include/asm/hugetlb.h               |  8 ++++----
 mm/hugetlb.c                                 |  6 +++---
 22 files changed, 76 insertions(+), 67 deletions(-)

diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
index d4014fbe5ea3..b71839e1786f 100644
--- a/arch/arm/include/asm/hugetlb-3level.h
+++ b/arch/arm/include/asm/hugetlb-3level.h
@@ -49,16 +49,16 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 	ptep_clear_flush(vma, addr, ptep);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index bbc1e35aa601..4e54d4b58d3e 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -76,9 +76,9 @@ extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 				      unsigned long addr, pte_t *ptep,
 				      pte_t pte, int dirty);
-extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+extern pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 				     unsigned long addr, pte_t *ptep);
-extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
+extern void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 				    unsigned long addr, pte_t *ptep);
 extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
 				  unsigned long addr, pte_t *ptep);
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 2e49bd252fe7..5c8903433cd9 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -197,10 +197,11 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 	return entry;
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep)
 {
 	pte_t pte;
+	struct mm_struct *mm = vma->vm_mm;
 
 	if (pte_cont(*ptep)) {
 		int ncontig, i;
@@ -263,9 +264,11 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 	}
 }
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 			     unsigned long addr, pte_t *ptep)
 {
+	struct mm_struct *mm = vma->vm_mm;
+
 	if (pte_cont(*ptep)) {
 		int ncontig, i;
 		pte_t *cpte;
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
index ef65f026b11e..eb1c1d674200 100644
--- a/arch/ia64/include/asm/hugetlb.h
+++ b/arch/ia64/include/asm/hugetlb.h
@@ -26,10 +26,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -47,10 +47,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h
index 905ed422dbeb..310b103127a6 100644
--- a/arch/metag/include/asm/hugetlb.h
+++ b/arch/metag/include/asm/hugetlb.h
@@ -28,10 +28,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -49,10 +49,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index 982bc0685330..4380acbff8e2 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -53,11 +53,12 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 	pte_t clear;
 	pte_t pte = *ptep;
+	struct mm_struct *mm = vma->vm_mm;
 
 	pte_val(clear) = (unsigned long)invalid_pte_table;
 	set_pte_at(mm, addr, ptep, clear);
@@ -81,10 +82,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
index a65d888716c4..3a6070842016 100644
--- a/arch/parisc/include/asm/hugetlb.h
+++ b/arch/parisc/include/asm/hugetlb.h
@@ -8,7 +8,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep);
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
@@ -54,7 +54,7 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep);
 
 int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index 5d6eea925cf4..e01fd08ed72c 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -142,11 +142,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 }
 
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep)
 {
 	unsigned long flags;
 	pte_t entry;
+	struct mm_struct *mm = vma->vma_mm;
 
 	purge_tlb_start(flags);
 	entry = *ptep;
@@ -157,11 +158,12 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 }
 
 
-void huge_ptep_set_wrprotect(struct mm_struct *mm,
+void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep)
 {
 	unsigned long flags;
 	pte_t old_pte;
+	struct mm_struct *mm = vma->vm_mm;
 
 	purge_tlb_start(flags);
 	old_pte = *ptep;
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 0713626e9189..34c8fd0c5d04 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -216,10 +216,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 {
 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
 }
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 
diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index a7d2b6107383..58e00dbbf15c 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -28,4 +28,14 @@ static inline int hstate_get_psize(struct hstate *hstate)
 		return mmu_virtual_psize;
 	}
 }
+
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
+					   unsigned long addr, pte_t *ptep)
+{
+	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
+		return;
+
+	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
+}
+
 #endif
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 46d739457d68..ef2eef1ba99a 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -346,15 +346,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
-					   unsigned long addr, pte_t *ptep)
-{
-	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
-		return;
-
-	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
-}
-
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pte_t *ptep)
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index c03e0a3dd4d8..b152e0c8dc4e 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -132,11 +132,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 #ifdef CONFIG_PPC64
-	return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
+	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
 #else
 	return __pte(pte_update(ptep, ~0UL, 0));
 #endif
@@ -146,7 +146,7 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long addr, pte_t *ptep)
 {
 	pte_t pte;
-	pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+	pte = huge_ptep_get_and_clear(vma, addr, ptep);
 	flush_hugetlb_page(vma, addr);
 }
 
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 24ee66bf7223..db83c15f1d54 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -260,10 +260,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 {
 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
 }
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 86d49dc60ec6..16c77d923209 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -257,13 +257,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	if ((pte_val(*ptep) & _PAGE_RW) == 0)
 		return;
 
-	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
+	pte_update(vma->vm_mm, addr, ptep, _PAGE_RW, 0, 1);
 }
 
 /*
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 4c7fac75090e..eb411d59ab77 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -19,7 +19,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 pte_t huge_ptep_get(pte_t *ptep);
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep);
 
 /*
@@ -50,7 +50,7 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long address, pte_t *ptep)
 {
-	huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
+	huge_ptep_get_and_clear(vma, address, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
@@ -59,17 +59,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 {
 	int changed = !pte_same(huge_ptep_get(ptep), pte);
 	if (changed) {
-		huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+		huge_ptep_get_and_clear(vma, addr, ptep);
 		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 	}
 	return changed;
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep);
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
+	pte_t pte = huge_ptep_get_and_clear(vma, addr, ptep);
+	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(pte));
 }
 
 static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index cd404aa3931c..61146137b0d2 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -136,12 +136,13 @@ pte_t huge_ptep_get(pte_t *ptep)
 	return __rste_to_pte(pte_val(*ptep));
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 			      unsigned long addr, pte_t *ptep)
 {
 	pte_t pte = huge_ptep_get(ptep);
 	pmd_t *pmdp = (pmd_t *) ptep;
 	pud_t *pudp = (pud_t *) ptep;
+	struct mm_struct *mm = vma->vm_mm;
 
 	if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
 		pudp_xchg_direct(mm, addr, pudp, __pud(_REGION3_ENTRY_EMPTY));
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index ef489a56fcce..925cbc0b4da9 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -40,10 +40,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -61,10 +61,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index dcbf985ab243..c7c21738b46c 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -8,7 +8,7 @@
 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t pte);
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep);
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
@@ -46,11 +46,11 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	pte_t old_pte = *ptep;
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(old_pte));
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 988acc8b1b80..c5d1fb4a83a7 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -174,10 +174,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, orig, 0);
 }
 
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
 			      pte_t *ptep)
 {
 	pte_t entry;
+	struct mm_struct *mm = vma->vm_mm;
 
 	entry = *ptep;
 	if (pte_present(entry))
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index 2fac5be4de26..aab3ff1cdb10 100644
--- a/arch/tile/include/asm/hugetlb.h
+++ b/arch/tile/include/asm/hugetlb.h
@@ -54,10 +54,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte(ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -76,10 +76,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
index 3a106165e03a..47b7a102a6a2 100644
--- a/arch/x86/include/asm/hugetlb.h
+++ b/arch/x86/include/asm/hugetlb.h
@@ -41,10 +41,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte_at(mm, addr, ptep, pte);
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-	return ptep_get_and_clear(mm, addr, ptep);
+	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -63,10 +63,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
-	ptep_set_wrprotect(mm, addr, ptep);
+	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ec49d9ef1eef..6b140f213e33 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3182,7 +3182,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			set_huge_pte_at(dst, addr, dst_pte, entry);
 		} else {
 			if (cow) {
-				huge_ptep_set_wrprotect(src, addr, src_pte);
+				huge_ptep_set_wrprotect(vma, addr, src_pte);
 				mmu_notifier_invalidate_range(src, mmun_start,
 								   mmun_end);
 			}
@@ -3271,7 +3271,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 			set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED);
 		}
 
-		pte = huge_ptep_get_and_clear(mm, address, ptep);
+		pte = huge_ptep_get_and_clear(vma, address, ptep);
 		tlb_remove_tlb_entry(tlb, ptep, address);
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
@@ -4020,7 +4020,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 			continue;
 		}
 		if (!huge_pte_none(pte)) {
-			pte = huge_ptep_get_and_clear(mm, address, ptep);
+			pte = huge_ptep_get_and_clear(vma, address, ptep);
 			pte = pte_mkhuge(huge_pte_modify(pte, newprot));
 			pte = arch_make_huge_pte(pte, vma, NULL, 0);
 			set_huge_pte_at(mm, address, ptep, pte);
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] powerpc/mm: update pte_update to not do full mm tlb flush
  2016-11-10  9:29 ` Aneesh Kumar K.V
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  -1 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

When we are updating pte, we just need to flush the tlb mapping for
that pte. Right now we do a full mm flush because we don't track page
size. Update the interface to track the page size and use that to
do the right tlb flush.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/64/hugetlb.h | 16 +++++++++++++++-
 arch/powerpc/include/asm/book3s/64/pgtable.h | 16 ++++++++++------
 arch/powerpc/include/asm/book3s/64/radix.h   | 19 ++++++++-----------
 arch/powerpc/include/asm/hugetlb.h           |  2 +-
 arch/powerpc/mm/pgtable-radix.c              |  2 +-
 5 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 58e00dbbf15c..dfe917b40f26 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -29,13 +29,27 @@ static inline int hstate_get_psize(struct hstate *hstate)
 	}
 }
 
+static inline unsigned long huge_pte_update(struct vm_area_struct *vma, unsigned long addr,
+					    pte_t *ptep, unsigned long clr,
+					    unsigned long set)
+{
+	unsigned long pg_sz;
+
+	VM_WARN_ON(!is_vm_hugetlb_page(vma));
+	pg_sz = huge_page_size(hstate_vma(vma));
+
+	if (radix_enabled())
+		return radix__pte_update(vma->vm_mm, addr, ptep, clr, set, pg_sz);
+	return hash__pte_update(vma->vm_mm, addr, ptep, clr, set, true);
+}
+
 static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
 		return;
 
-	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
+	huge_pte_update(vma, addr, ptep, _PAGE_WRITE, 0);
 }
 
 #endif
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index ef2eef1ba99a..09869ad37aba 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -301,12 +301,16 @@ extern unsigned long pci_io_base;
 
 static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr,
 				       pte_t *ptep, unsigned long clr,
-				       unsigned long set, int huge)
+				       unsigned long set,
+				       unsigned long pg_sz)
 {
+	bool huge = (pg_sz != PAGE_SIZE);
+
 	if (radix_enabled())
-		return radix__pte_update(mm, addr, ptep, clr, set, huge);
+		return radix__pte_update(mm, addr, ptep, clr, set, pg_sz);
 	return hash__pte_update(mm, addr, ptep, clr, set, huge);
 }
+
 /*
  * For hash even if we have _PAGE_ACCESSED = 0, we do a pte_update.
  * We currently remove entries from the hashtable regardless of whether
@@ -324,7 +328,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
 
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_ACCESSED | H_PAGE_HASHPTE)) == 0)
 		return 0;
-	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
+	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, PAGE_SIZE);
 	return (old & _PAGE_ACCESSED) != 0;
 }
 
@@ -343,21 +347,21 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
 		return;
 
-	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
+	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, PAGE_SIZE);
 }
 
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pte_t *ptep)
 {
-	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
+	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, PAGE_SIZE);
 	return __pte(old);
 }
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 			     pte_t * ptep)
 {
-	pte_update(mm, addr, ptep, ~0UL, 0, 0);
+	pte_update(mm, addr, ptep, ~0UL, 0, PAGE_SIZE);
 }
 
 static inline int pte_write(pte_t pte)
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 279b2f68e00f..aec6e8ee6e27 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -129,15 +129,16 @@ static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
 
 
 static inline unsigned long radix__pte_update(struct mm_struct *mm,
-					unsigned long addr,
-					pte_t *ptep, unsigned long clr,
-					unsigned long set,
-					int huge)
+					      unsigned long addr,
+					      pte_t *ptep, unsigned long clr,
+					      unsigned long set,
+					      unsigned long pg_sz)
 {
 	unsigned long old_pte;
 
 	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
 
+		int psize;
 		unsigned long new_pte;
 
 		old_pte = __radix_pte_update(ptep, ~0, 0);
@@ -146,18 +147,14 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
 		 * new value of pte
 		 */
 		new_pte = (old_pte | set) & ~clr;
-
-		/*
-		 * For now let's do heavy pid flush
-		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
-		 */
-		radix__flush_tlb_mm(mm);
+		psize = radix_get_mmu_psize(pg_sz);
+		radix__flush_tlb_page_psize(mm, addr, psize);
 
 		__radix_pte_update(ptep, 0, new_pte);
 	} else
 		old_pte = __radix_pte_update(ptep, clr, set);
 	asm volatile("ptesync" : : : "memory");
-	if (!huge)
+	if (pg_sz == PAGE_SIZE)
 		assert_pte_locked(mm, addr);
 
 	return old_pte;
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index b152e0c8dc4e..f0731dff76c2 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -136,7 +136,7 @@ static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 #ifdef CONFIG_PPC64
-	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
+	return __pte(huge_pte_update(vma, addr, ptep, ~0UL, 0));
 #else
 	return __pte(pte_update(ptep, ~0UL, 0));
 #endif
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 6b1ffc449158..735be6821e90 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -482,7 +482,7 @@ unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long add
 	assert_spin_locked(&mm->page_table_lock);
 #endif
 
-	old = radix__pte_update(mm, addr, (pte_t *)pmdp, clr, set, 1);
+	old = radix__pte_update(mm, addr, (pte_t *)pmdp, clr, set, HPAGE_PMD_SIZE);
 	trace_hugepage_update(addr, old, clr, set);
 
 	return old;
-- 
2.10.2

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] powerpc/mm: update pte_update to not do full mm tlb flush
@ 2016-11-10  9:29   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-10  9:29 UTC (permalink / raw)
  To: benh, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm, Aneesh Kumar K.V

When we are updating pte, we just need to flush the tlb mapping for
that pte. Right now we do a full mm flush because we don't track page
size. Update the interface to track the page size and use that to
do the right tlb flush.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/64/hugetlb.h | 16 +++++++++++++++-
 arch/powerpc/include/asm/book3s/64/pgtable.h | 16 ++++++++++------
 arch/powerpc/include/asm/book3s/64/radix.h   | 19 ++++++++-----------
 arch/powerpc/include/asm/hugetlb.h           |  2 +-
 arch/powerpc/mm/pgtable-radix.c              |  2 +-
 5 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 58e00dbbf15c..dfe917b40f26 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -29,13 +29,27 @@ static inline int hstate_get_psize(struct hstate *hstate)
 	}
 }
 
+static inline unsigned long huge_pte_update(struct vm_area_struct *vma, unsigned long addr,
+					    pte_t *ptep, unsigned long clr,
+					    unsigned long set)
+{
+	unsigned long pg_sz;
+
+	VM_WARN_ON(!is_vm_hugetlb_page(vma));
+	pg_sz = huge_page_size(hstate_vma(vma));
+
+	if (radix_enabled())
+		return radix__pte_update(vma->vm_mm, addr, ptep, clr, set, pg_sz);
+	return hash__pte_update(vma->vm_mm, addr, ptep, clr, set, true);
+}
+
 static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
 					   unsigned long addr, pte_t *ptep)
 {
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
 		return;
 
-	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
+	huge_pte_update(vma, addr, ptep, _PAGE_WRITE, 0);
 }
 
 #endif
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index ef2eef1ba99a..09869ad37aba 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -301,12 +301,16 @@ extern unsigned long pci_io_base;
 
 static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr,
 				       pte_t *ptep, unsigned long clr,
-				       unsigned long set, int huge)
+				       unsigned long set,
+				       unsigned long pg_sz)
 {
+	bool huge = (pg_sz != PAGE_SIZE);
+
 	if (radix_enabled())
-		return radix__pte_update(mm, addr, ptep, clr, set, huge);
+		return radix__pte_update(mm, addr, ptep, clr, set, pg_sz);
 	return hash__pte_update(mm, addr, ptep, clr, set, huge);
 }
+
 /*
  * For hash even if we have _PAGE_ACCESSED = 0, we do a pte_update.
  * We currently remove entries from the hashtable regardless of whether
@@ -324,7 +328,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
 
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_ACCESSED | H_PAGE_HASHPTE)) == 0)
 		return 0;
-	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
+	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, PAGE_SIZE);
 	return (old & _PAGE_ACCESSED) != 0;
 }
 
@@ -343,21 +347,21 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
 		return;
 
-	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
+	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, PAGE_SIZE);
 }
 
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pte_t *ptep)
 {
-	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
+	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, PAGE_SIZE);
 	return __pte(old);
 }
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 			     pte_t * ptep)
 {
-	pte_update(mm, addr, ptep, ~0UL, 0, 0);
+	pte_update(mm, addr, ptep, ~0UL, 0, PAGE_SIZE);
 }
 
 static inline int pte_write(pte_t pte)
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 279b2f68e00f..aec6e8ee6e27 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -129,15 +129,16 @@ static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
 
 
 static inline unsigned long radix__pte_update(struct mm_struct *mm,
-					unsigned long addr,
-					pte_t *ptep, unsigned long clr,
-					unsigned long set,
-					int huge)
+					      unsigned long addr,
+					      pte_t *ptep, unsigned long clr,
+					      unsigned long set,
+					      unsigned long pg_sz)
 {
 	unsigned long old_pte;
 
 	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
 
+		int psize;
 		unsigned long new_pte;
 
 		old_pte = __radix_pte_update(ptep, ~0, 0);
@@ -146,18 +147,14 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
 		 * new value of pte
 		 */
 		new_pte = (old_pte | set) & ~clr;
-
-		/*
-		 * For now let's do heavy pid flush
-		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
-		 */
-		radix__flush_tlb_mm(mm);
+		psize = radix_get_mmu_psize(pg_sz);
+		radix__flush_tlb_page_psize(mm, addr, psize);
 
 		__radix_pte_update(ptep, 0, new_pte);
 	} else
 		old_pte = __radix_pte_update(ptep, clr, set);
 	asm volatile("ptesync" : : : "memory");
-	if (!huge)
+	if (pg_sz == PAGE_SIZE)
 		assert_pte_locked(mm, addr);
 
 	return old_pte;
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index b152e0c8dc4e..f0731dff76c2 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -136,7 +136,7 @@ static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
 #ifdef CONFIG_PPC64
-	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
+	return __pte(huge_pte_update(vma, addr, ptep, ~0UL, 0));
 #else
 	return __pte(pte_update(ptep, ~0UL, 0));
 #endif
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 6b1ffc449158..735be6821e90 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -482,7 +482,7 @@ unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long add
 	assert_spin_locked(&mm->page_table_lock);
 #endif
 
-	old = radix__pte_update(mm, addr, (pte_t *)pmdp, clr, set, 1);
+	old = radix__pte_update(mm, addr, (pte_t *)pmdp, clr, set, HPAGE_PMD_SIZE);
 	trace_hugepage_update(addr, old, clr, set);
 
 	return old;
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
  2016-11-10  9:29   ` Aneesh Kumar K.V
@ 2016-11-10 19:36     ` Benjamin Herrenschmidt
  -1 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2016-11-10 19:36 UTC (permalink / raw)
  To: Aneesh Kumar K.V, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm

On Thu, 2016-11-10 at 14:59 +0530, Aneesh Kumar K.V wrote:
> This help us to find the hugetlb page size which we need ot use on some
> archs like ppc64 for tlbflush. This also make the interface consistent
> with other hugetlb functions

What about my requested simpler approach ?

For normal (non-huge) pages, we already know the size.

For huge pages, can't we encode in the top SW bits of the PTE the
page size that we obtain from set_pte_at ?

That would be a lot less churn and avoid touching all these archs...
especially since the current DD1 workaround is horrible and I want
the fix to be backported, so something simpler and contained in
arch/powerpc feels more suitable.

Ben.


> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> A arch/arm/include/asm/hugetlb-3level.hA A A A A A A A |A A 8 ++++----
> A arch/arm64/include/asm/hugetlb.hA A A A A A A A A A A A A |A A 4 ++--
> A arch/arm64/mm/hugetlbpage.cA A A A A A A A A A A A A A A A A A |A A 7 +++++--
> A arch/ia64/include/asm/hugetlb.hA A A A A A A A A A A A A A |A A 8 ++++----
> A arch/metag/include/asm/hugetlb.hA A A A A A A A A A A A A |A A 8 ++++----
> A arch/mips/include/asm/hugetlb.hA A A A A A A A A A A A A A |A A 7 ++++---
> A arch/parisc/include/asm/hugetlb.hA A A A A A A A A A A A |A A 4 ++--
> A arch/parisc/mm/hugetlbpage.cA A A A A A A A A A A A A A A A A |A A 6 ++++--
> A arch/powerpc/include/asm/book3s/32/pgtable.h |A A 4 ++--
> A arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
> A arch/powerpc/include/asm/book3s/64/pgtable.h |A A 9 ---------
> A arch/powerpc/include/asm/hugetlb.hA A A A A A A A A A A |A A 6 +++---
> A arch/powerpc/include/asm/nohash/32/pgtable.h |A A 4 ++--
> A arch/powerpc/include/asm/nohash/64/pgtable.h |A A 4 ++--
> A arch/s390/include/asm/hugetlb.hA A A A A A A A A A A A A A | 12 ++++++------
> A arch/s390/mm/hugetlbpage.cA A A A A A A A A A A A A A A A A A A |A A 3 ++-
> A arch/sh/include/asm/hugetlb.hA A A A A A A A A A A A A A A A |A A 8 ++++----
> A arch/sparc/include/asm/hugetlb.hA A A A A A A A A A A A A |A A 6 +++---
> A arch/sparc/mm/hugetlbpage.cA A A A A A A A A A A A A A A A A A |A A 3 ++-
> A arch/tile/include/asm/hugetlb.hA A A A A A A A A A A A A A |A A 8 ++++----
> A arch/x86/include/asm/hugetlb.hA A A A A A A A A A A A A A A |A A 8 ++++----
> A mm/hugetlb.cA A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A |A A 6 +++---
> A 22 files changed, 76 insertions(+), 67 deletions(-)
> 
> diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
> index d4014fbe5ea3..b71839e1786f 100644
> --- a/arch/arm/include/asm/hugetlb-3level.h
> +++ b/arch/arm/include/asm/hugetlb-3level.h
> @@ -49,16 +49,16 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> > A 	ptep_clear_flush(vma, addr, ptep);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
> index bbc1e35aa601..4e54d4b58d3e 100644
> --- a/arch/arm64/include/asm/hugetlb.h
> +++ b/arch/arm64/include/asm/hugetlb.h
> @@ -76,9 +76,9 @@ extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> A extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> > A 				A A A A A A unsigned long addr, pte_t *ptep,
> > A 				A A A A A A pte_t pte, int dirty);
> -extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +extern pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 				A A A A A unsigned long addr, pte_t *ptep);
> -extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +extern void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 				A A A A unsigned long addr, pte_t *ptep);
> A extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
> > A 				A A unsigned long addr, pte_t *ptep);
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 2e49bd252fe7..5c8903433cd9 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -197,10 +197,11 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
> > A 	return entry;
> A }
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 			A A A A A A unsigned long addr, pte_t *ptep)
> A {
> > A 	pte_t pte;
> > +	struct mm_struct *mm = vma->vm_mm;
> A 
> > A 	if (pte_cont(*ptep)) {
> > A 		int ncontig, i;
> @@ -263,9 +264,11 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> > A 	}
> A }
> A 
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 			A A A A A unsigned long addr, pte_t *ptep)
> A {
> > +	struct mm_struct *mm = vma->vm_mm;
> +
> > A 	if (pte_cont(*ptep)) {
> > A 		int ncontig, i;
> > A 		pte_t *cpte;
> diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
> index ef65f026b11e..eb1c1d674200 100644
> --- a/arch/ia64/include/asm/hugetlb.h
> +++ b/arch/ia64/include/asm/hugetlb.h
> @@ -26,10 +26,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -47,10 +47,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h
> index 905ed422dbeb..310b103127a6 100644
> --- a/arch/metag/include/asm/hugetlb.h
> +++ b/arch/metag/include/asm/hugetlb.h
> @@ -28,10 +28,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -49,10 +49,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
> index 982bc0685330..4380acbff8e2 100644
> --- a/arch/mips/include/asm/hugetlb.h
> +++ b/arch/mips/include/asm/hugetlb.h
> @@ -53,11 +53,12 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > A 	pte_t clear;
> > A 	pte_t pte = *ptep;
> > +	struct mm_struct *mm = vma->vm_mm;
> A 
> > A 	pte_val(clear) = (unsigned long)invalid_pte_table;
> > A 	set_pte_at(mm, addr, ptep, clear);
> @@ -81,10 +82,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
> index a65d888716c4..3a6070842016 100644
> --- a/arch/parisc/include/asm/hugetlb.h
> +++ b/arch/parisc/include/asm/hugetlb.h
> @@ -8,7 +8,7 @@
> A void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 		A A A A A pte_t *ptep, pte_t pte);
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> > A 			A A A A A A pte_t *ptep);
> A 
> A static inline int is_hugepage_only_range(struct mm_struct *mm,
> @@ -54,7 +54,7 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep);
> A 
> A int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
> index 5d6eea925cf4..e01fd08ed72c 100644
> --- a/arch/parisc/mm/hugetlbpage.c
> +++ b/arch/parisc/mm/hugetlbpage.c
> @@ -142,11 +142,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> A }
> A 
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> > A 			A A A A A A pte_t *ptep)
> A {
> > A 	unsigned long flags;
> > A 	pte_t entry;
> > +	struct mm_struct *mm = vma->vma_mm;
> A 
> > A 	purge_tlb_start(flags);
> > A 	entry = *ptep;
> @@ -157,11 +158,12 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> A }
> A 
> A 
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 				unsigned long addr, pte_t *ptep)
> A {
> > A 	unsigned long flags;
> > A 	pte_t old_pte;
> > +	struct mm_struct *mm = vma->vm_mm;
> A 
> > A 	purge_tlb_start(flags);
> > A 	old_pte = *ptep;
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 0713626e9189..34c8fd0c5d04 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -216,10 +216,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> A {
> > A 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
> A }
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A 
> diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> index a7d2b6107383..58e00dbbf15c 100644
> --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
> +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> @@ -28,4 +28,14 @@ static inline int hstate_get_psize(struct hstate *hstate)
> > A 		return mmu_virtual_psize;
> > A 	}
> A }
> +
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > +					A A A unsigned long addr, pte_t *ptep)
> +{
> > +	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
> > +		return;
> +
> > +	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
> +}
> +
> A #endif
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
> index 46d739457d68..ef2eef1ba99a 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -346,15 +346,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> > A 	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> > -					A A A unsigned long addr, pte_t *ptep)
> -{
> > -	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
> > -		return;
> -
> > -	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
> -}
> -
> A #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
> A static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
> > A 				A A A A A A A unsigned long addr, pte_t *ptep)
> diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
> index c03e0a3dd4d8..b152e0c8dc4e 100644
> --- a/arch/powerpc/include/asm/hugetlb.h
> +++ b/arch/powerpc/include/asm/hugetlb.h
> @@ -132,11 +132,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> A #ifdef CONFIG_PPC64
> > -	return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
> > +	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
> A #else
> > A 	return __pte(pte_update(ptep, ~0UL, 0));
> A #endif
> @@ -146,7 +146,7 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> > A 					A unsigned long addr, pte_t *ptep)
> A {
> > A 	pte_t pte;
> > -	pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> > +	pte = huge_ptep_get_and_clear(vma, addr, ptep);
> > A 	flush_hugetlb_page(vma, addr);
> A }
> A 
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index 24ee66bf7223..db83c15f1d54 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -260,10 +260,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> A {
> > A 	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
> A }
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A 
> diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
> index 86d49dc60ec6..16c77d923209 100644
> --- a/arch/powerpc/include/asm/nohash/64/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
> @@ -257,13 +257,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> > A 	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > A 	if ((pte_val(*ptep) & _PAGE_RW) == 0)
> > A 		return;
> A 
> > -	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
> > +	pte_update(vma->vm_mm, addr, ptep, _PAGE_RW, 0, 1);
> A }
> A 
> A /*
> diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
> index 4c7fac75090e..eb411d59ab77 100644
> --- a/arch/s390/include/asm/hugetlb.h
> +++ b/arch/s390/include/asm/hugetlb.h
> @@ -19,7 +19,7 @@
> A void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 		A A A A A pte_t *ptep, pte_t pte);
> A pte_t huge_ptep_get(pte_t *ptep);
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 			A A A A A A unsigned long addr, pte_t *ptep);
> A 
> A /*
> @@ -50,7 +50,7 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> > A 					A unsigned long address, pte_t *ptep)
> A {
> > -	huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
> > +	huge_ptep_get_and_clear(vma, address, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> @@ -59,17 +59,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> A {
> > A 	int changed = !pte_same(huge_ptep_get(ptep), pte);
> > A 	if (changed) {
> > -		huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> > +		huge_ptep_get_and_clear(vma, addr, ptep);
> > A 		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> > A 	}
> > A 	return changed;
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep);
> > -	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
> > +	pte_t pte = huge_ptep_get_and_clear(vma, addr, ptep);
> > +	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(pte));
> A }
> A 
> A static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
> diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
> index cd404aa3931c..61146137b0d2 100644
> --- a/arch/s390/mm/hugetlbpage.c
> +++ b/arch/s390/mm/hugetlbpage.c
> @@ -136,12 +136,13 @@ pte_t huge_ptep_get(pte_t *ptep)
> > A 	return __rste_to_pte(pte_val(*ptep));
> A }
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 			A A A A A A unsigned long addr, pte_t *ptep)
> A {
> > A 	pte_t pte = huge_ptep_get(ptep);
> > A 	pmd_t *pmdp = (pmd_t *) ptep;
> > A 	pud_t *pudp = (pud_t *) ptep;
> > +	struct mm_struct *mm = vma->vm_mm;
> A 
> > A 	if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
> > A 		pudp_xchg_direct(mm, addr, pudp, __pud(_REGION3_ENTRY_EMPTY));
> diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
> index ef489a56fcce..925cbc0b4da9 100644
> --- a/arch/sh/include/asm/hugetlb.h
> +++ b/arch/sh/include/asm/hugetlb.h
> @@ -40,10 +40,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -61,10 +61,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
> index dcbf985ab243..c7c21738b46c 100644
> --- a/arch/sparc/include/asm/hugetlb.h
> +++ b/arch/sparc/include/asm/hugetlb.h
> @@ -8,7 +8,7 @@
> A void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 		A A A A A pte_t *ptep, pte_t pte);
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> > A 			A A A A A A pte_t *ptep);
> A 
> A static inline int is_hugepage_only_range(struct mm_struct *mm,
> @@ -46,11 +46,11 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > A 	pte_t old_pte = *ptep;
> > -	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
> > +	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(old_pte));
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
> index 988acc8b1b80..c5d1fb4a83a7 100644
> --- a/arch/sparc/mm/hugetlbpage.c
> +++ b/arch/sparc/mm/hugetlbpage.c
> @@ -174,10 +174,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, orig, 0);
> A }
> A 
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> > A 			A A A A A A pte_t *ptep)
> A {
> > A 	pte_t entry;
> > +	struct mm_struct *mm = vma->vm_mm;
> A 
> > A 	entry = *ptep;
> > A 	if (pte_present(entry))
> diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
> index 2fac5be4de26..aab3ff1cdb10 100644
> --- a/arch/tile/include/asm/hugetlb.h
> +++ b/arch/tile/include/asm/hugetlb.h
> @@ -54,10 +54,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte(ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -76,10 +76,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
> index 3a106165e03a..47b7a102a6a2 100644
> --- a/arch/x86/include/asm/hugetlb.h
> +++ b/arch/x86/include/asm/hugetlb.h
> @@ -41,10 +41,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> > A 	set_pte_at(mm, addr, ptep, pte);
> A }
> A 
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> > A 					A A A A unsigned long addr, pte_t *ptep)
> A {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -63,10 +63,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> > A 	return pte_wrprotect(pte);
> A }
> A 
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > A 					A A A unsigned long addr, pte_t *ptep)
> A {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
> A }
> A 
> A static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index ec49d9ef1eef..6b140f213e33 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -3182,7 +3182,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
> > A 			set_huge_pte_at(dst, addr, dst_pte, entry);
> > A 		} else {
> > A 			if (cow) {
> > -				huge_ptep_set_wrprotect(src, addr, src_pte);
> > +				huge_ptep_set_wrprotect(vma, addr, src_pte);
> > A 				mmu_notifier_invalidate_range(src, mmun_start,
> > A 								A A A mmun_end);
> > A 			}
> @@ -3271,7 +3271,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
> > A 			set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED);
> > A 		}
> A 
> > -		pte = huge_ptep_get_and_clear(mm, address, ptep);
> > +		pte = huge_ptep_get_and_clear(vma, address, ptep);
> > A 		tlb_remove_tlb_entry(tlb, ptep, address);
> > A 		if (huge_pte_dirty(pte))
> > A 			set_page_dirty(page);
> @@ -4020,7 +4020,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
> > A 			continue;
> > A 		}
> > A 		if (!huge_pte_none(pte)) {
> > -			pte = huge_ptep_get_and_clear(mm, address, ptep);
> > +			pte = huge_ptep_get_and_clear(vma, address, ptep);
> > A 			pte = pte_mkhuge(huge_pte_modify(pte, newprot));
> > A 			pte = arch_make_huge_pte(pte, vma, NULL, 0);
> > A 			set_huge_pte_at(mm, address, ptep, pte);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
@ 2016-11-10 19:36     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 12+ messages in thread
From: Benjamin Herrenschmidt @ 2016-11-10 19:36 UTC (permalink / raw)
  To: Aneesh Kumar K.V, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm

On Thu, 2016-11-10 at 14:59 +0530, Aneesh Kumar K.V wrote:
> This help us to find the hugetlb page size which we need ot use on some
> archs like ppc64 for tlbflush. This also make the interface consistent
> with other hugetlb functions

What about my requested simpler approach ?

For normal (non-huge) pages, we already know the size.

For huge pages, can't we encode in the top SW bits of the PTE the
page size that we obtain from set_pte_at ?

That would be a lot less churn and avoid touching all these archs...
especially since the current DD1 workaround is horrible and I want
the fix to be backported, so something simpler and contained in
arch/powerpc feels more suitable.

Ben.


> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  arch/arm/include/asm/hugetlb-3level.h        |  8 ++++----
>  arch/arm64/include/asm/hugetlb.h             |  4 ++--
>  arch/arm64/mm/hugetlbpage.c                  |  7 +++++--
>  arch/ia64/include/asm/hugetlb.h              |  8 ++++----
>  arch/metag/include/asm/hugetlb.h             |  8 ++++----
>  arch/mips/include/asm/hugetlb.h              |  7 ++++---
>  arch/parisc/include/asm/hugetlb.h            |  4 ++--
>  arch/parisc/mm/hugetlbpage.c                 |  6 ++++--
>  arch/powerpc/include/asm/book3s/32/pgtable.h |  4 ++--
>  arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
>  arch/powerpc/include/asm/book3s/64/pgtable.h |  9 ---------
>  arch/powerpc/include/asm/hugetlb.h           |  6 +++---
>  arch/powerpc/include/asm/nohash/32/pgtable.h |  4 ++--
>  arch/powerpc/include/asm/nohash/64/pgtable.h |  4 ++--
>  arch/s390/include/asm/hugetlb.h              | 12 ++++++------
>  arch/s390/mm/hugetlbpage.c                   |  3 ++-
>  arch/sh/include/asm/hugetlb.h                |  8 ++++----
>  arch/sparc/include/asm/hugetlb.h             |  6 +++---
>  arch/sparc/mm/hugetlbpage.c                  |  3 ++-
>  arch/tile/include/asm/hugetlb.h              |  8 ++++----
>  arch/x86/include/asm/hugetlb.h               |  8 ++++----
>  mm/hugetlb.c                                 |  6 +++---
>  22 files changed, 76 insertions(+), 67 deletions(-)
> 
> diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
> index d4014fbe5ea3..b71839e1786f 100644
> --- a/arch/arm/include/asm/hugetlb-3level.h
> +++ b/arch/arm/include/asm/hugetlb-3level.h
> @@ -49,16 +49,16 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >  	ptep_clear_flush(vma, addr, ptep);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
> index bbc1e35aa601..4e54d4b58d3e 100644
> --- a/arch/arm64/include/asm/hugetlb.h
> +++ b/arch/arm64/include/asm/hugetlb.h
> @@ -76,9 +76,9 @@ extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> >  				      unsigned long addr, pte_t *ptep,
> >  				      pte_t pte, int dirty);
> -extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +extern pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  				     unsigned long addr, pte_t *ptep);
> -extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +extern void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  				    unsigned long addr, pte_t *ptep);
>  extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >  				  unsigned long addr, pte_t *ptep);
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 2e49bd252fe7..5c8903433cd9 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -197,10 +197,11 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
> >  	return entry;
>  }
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  			      unsigned long addr, pte_t *ptep)
>  {
> >  	pte_t pte;
> > +	struct mm_struct *mm = vma->vm_mm;
>  
> >  	if (pte_cont(*ptep)) {
> >  		int ncontig, i;
> @@ -263,9 +264,11 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> >  	}
>  }
>  
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  			     unsigned long addr, pte_t *ptep)
>  {
> > +	struct mm_struct *mm = vma->vm_mm;
> +
> >  	if (pte_cont(*ptep)) {
> >  		int ncontig, i;
> >  		pte_t *cpte;
> diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
> index ef65f026b11e..eb1c1d674200 100644
> --- a/arch/ia64/include/asm/hugetlb.h
> +++ b/arch/ia64/include/asm/hugetlb.h
> @@ -26,10 +26,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -47,10 +47,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h
> index 905ed422dbeb..310b103127a6 100644
> --- a/arch/metag/include/asm/hugetlb.h
> +++ b/arch/metag/include/asm/hugetlb.h
> @@ -28,10 +28,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -49,10 +49,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
> index 982bc0685330..4380acbff8e2 100644
> --- a/arch/mips/include/asm/hugetlb.h
> +++ b/arch/mips/include/asm/hugetlb.h
> @@ -53,11 +53,12 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> >  	pte_t clear;
> >  	pte_t pte = *ptep;
> > +	struct mm_struct *mm = vma->vm_mm;
>  
> >  	pte_val(clear) = (unsigned long)invalid_pte_table;
> >  	set_pte_at(mm, addr, ptep, clear);
> @@ -81,10 +82,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
> index a65d888716c4..3a6070842016 100644
> --- a/arch/parisc/include/asm/hugetlb.h
> +++ b/arch/parisc/include/asm/hugetlb.h
> @@ -8,7 +8,7 @@
>  void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  		     pte_t *ptep, pte_t pte);
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> >  			      pte_t *ptep);
>  
>  static inline int is_hugepage_only_range(struct mm_struct *mm,
> @@ -54,7 +54,7 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep);
>  
>  int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
> index 5d6eea925cf4..e01fd08ed72c 100644
> --- a/arch/parisc/mm/hugetlbpage.c
> +++ b/arch/parisc/mm/hugetlbpage.c
> @@ -142,11 +142,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  }
>  
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> >  			      pte_t *ptep)
>  {
> >  	unsigned long flags;
> >  	pte_t entry;
> > +	struct mm_struct *mm = vma->vma_mm;
>  
> >  	purge_tlb_start(flags);
> >  	entry = *ptep;
> @@ -157,11 +158,12 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
>  }
>  
>  
> -void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  				unsigned long addr, pte_t *ptep)
>  {
> >  	unsigned long flags;
> >  	pte_t old_pte;
> > +	struct mm_struct *mm = vma->vm_mm;
>  
> >  	purge_tlb_start(flags);
> >  	old_pte = *ptep;
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 0713626e9189..34c8fd0c5d04 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -216,10 +216,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
>  {
> >  	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
>  }
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  
> diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> index a7d2b6107383..58e00dbbf15c 100644
> --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
> +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> @@ -28,4 +28,14 @@ static inline int hstate_get_psize(struct hstate *hstate)
> >  		return mmu_virtual_psize;
> >  	}
>  }
> +
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> > +					   unsigned long addr, pte_t *ptep)
> +{
> > +	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
> > +		return;
> +
> > +	pte_update(vma->vm_mm, addr, ptep, _PAGE_WRITE, 0, 1);
> +}
> +
>  #endif
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
> index 46d739457d68..ef2eef1ba99a 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -346,15 +346,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> >  	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> > -					   unsigned long addr, pte_t *ptep)
> -{
> > -	if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
> > -		return;
> -
> > -	pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
> -}
> -
>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
> >  				       unsigned long addr, pte_t *ptep)
> diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
> index c03e0a3dd4d8..b152e0c8dc4e 100644
> --- a/arch/powerpc/include/asm/hugetlb.h
> +++ b/arch/powerpc/include/asm/hugetlb.h
> @@ -132,11 +132,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
>  #ifdef CONFIG_PPC64
> > -	return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
> > +	return __pte(pte_update(vma->vm_mm, addr, ptep, ~0UL, 0, 1));
>  #else
> >  	return __pte(pte_update(ptep, ~0UL, 0));
>  #endif
> @@ -146,7 +146,7 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >  					 unsigned long addr, pte_t *ptep)
>  {
> >  	pte_t pte;
> > -	pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> > +	pte = huge_ptep_get_and_clear(vma, addr, ptep);
> >  	flush_hugetlb_page(vma, addr);
>  }
>  
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index 24ee66bf7223..db83c15f1d54 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -260,10 +260,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
>  {
> >  	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
>  }
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  
> diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
> index 86d49dc60ec6..16c77d923209 100644
> --- a/arch/powerpc/include/asm/nohash/64/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
> @@ -257,13 +257,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> >  	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> >  	if ((pte_val(*ptep) & _PAGE_RW) == 0)
> >  		return;
>  
> > -	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
> > +	pte_update(vma->vm_mm, addr, ptep, _PAGE_RW, 0, 1);
>  }
>  
>  /*
> diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
> index 4c7fac75090e..eb411d59ab77 100644
> --- a/arch/s390/include/asm/hugetlb.h
> +++ b/arch/s390/include/asm/hugetlb.h
> @@ -19,7 +19,7 @@
>  void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  		     pte_t *ptep, pte_t pte);
>  pte_t huge_ptep_get(pte_t *ptep);
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  			      unsigned long addr, pte_t *ptep);
>  
>  /*
> @@ -50,7 +50,7 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >  					 unsigned long address, pte_t *ptep)
>  {
> > -	huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
> > +	huge_ptep_get_and_clear(vma, address, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> @@ -59,17 +59,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>  {
> >  	int changed = !pte_same(huge_ptep_get(ptep), pte);
> >  	if (changed) {
> > -		huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> > +		huge_ptep_get_and_clear(vma, addr, ptep);
> >  		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
> >  	}
> >  	return changed;
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep);
> > -	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
> > +	pte_t pte = huge_ptep_get_and_clear(vma, addr, ptep);
> > +	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(pte));
>  }
>  
>  static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
> diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
> index cd404aa3931c..61146137b0d2 100644
> --- a/arch/s390/mm/hugetlbpage.c
> +++ b/arch/s390/mm/hugetlbpage.c
> @@ -136,12 +136,13 @@ pte_t huge_ptep_get(pte_t *ptep)
> >  	return __rste_to_pte(pte_val(*ptep));
>  }
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  			      unsigned long addr, pte_t *ptep)
>  {
> >  	pte_t pte = huge_ptep_get(ptep);
> >  	pmd_t *pmdp = (pmd_t *) ptep;
> >  	pud_t *pudp = (pud_t *) ptep;
> > +	struct mm_struct *mm = vma->vm_mm;
>  
> >  	if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
> >  		pudp_xchg_direct(mm, addr, pudp, __pud(_REGION3_ENTRY_EMPTY));
> diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
> index ef489a56fcce..925cbc0b4da9 100644
> --- a/arch/sh/include/asm/hugetlb.h
> +++ b/arch/sh/include/asm/hugetlb.h
> @@ -40,10 +40,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -61,10 +61,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
> index dcbf985ab243..c7c21738b46c 100644
> --- a/arch/sparc/include/asm/hugetlb.h
> +++ b/arch/sparc/include/asm/hugetlb.h
> @@ -8,7 +8,7 @@
>  void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  		     pte_t *ptep, pte_t pte);
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> >  			      pte_t *ptep);
>  
>  static inline int is_hugepage_only_range(struct mm_struct *mm,
> @@ -46,11 +46,11 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> >  	pte_t old_pte = *ptep;
> > -	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
> > +	set_huge_pte_at(vma->vm_mm, addr, ptep, pte_wrprotect(old_pte));
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
> index 988acc8b1b80..c5d1fb4a83a7 100644
> --- a/arch/sparc/mm/hugetlbpage.c
> +++ b/arch/sparc/mm/hugetlbpage.c
> @@ -174,10 +174,11 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, orig, 0);
>  }
>  
> -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
> +pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma, unsigned long addr,
> >  			      pte_t *ptep)
>  {
> >  	pte_t entry;
> > +	struct mm_struct *mm = vma->vm_mm;
>  
> >  	entry = *ptep;
> >  	if (pte_present(entry))
> diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
> index 2fac5be4de26..aab3ff1cdb10 100644
> --- a/arch/tile/include/asm/hugetlb.h
> +++ b/arch/tile/include/asm/hugetlb.h
> @@ -54,10 +54,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte(ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -76,10 +76,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
> index 3a106165e03a..47b7a102a6a2 100644
> --- a/arch/x86/include/asm/hugetlb.h
> +++ b/arch/x86/include/asm/hugetlb.h
> @@ -41,10 +41,10 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
> >  	set_pte_at(mm, addr, ptep, pte);
>  }
>  
> -static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t huge_ptep_get_and_clear(struct vm_area_struct *vma,
> >  					    unsigned long addr, pte_t *ptep)
>  {
> > -	return ptep_get_and_clear(mm, addr, ptep);
> > +	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -63,10 +63,10 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
> >  	return pte_wrprotect(pte);
>  }
>  
> -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
> +static inline void huge_ptep_set_wrprotect(struct vm_area_struct *vma,
> >  					   unsigned long addr, pte_t *ptep)
>  {
> > -	ptep_set_wrprotect(mm, addr, ptep);
> > +	ptep_set_wrprotect(vma->vm_mm, addr, ptep);
>  }
>  
>  static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index ec49d9ef1eef..6b140f213e33 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -3182,7 +3182,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
> >  			set_huge_pte_at(dst, addr, dst_pte, entry);
> >  		} else {
> >  			if (cow) {
> > -				huge_ptep_set_wrprotect(src, addr, src_pte);
> > +				huge_ptep_set_wrprotect(vma, addr, src_pte);
> >  				mmu_notifier_invalidate_range(src, mmun_start,
> >  								   mmun_end);
> >  			}
> @@ -3271,7 +3271,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
> >  			set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED);
> >  		}
>  
> > -		pte = huge_ptep_get_and_clear(mm, address, ptep);
> > +		pte = huge_ptep_get_and_clear(vma, address, ptep);
> >  		tlb_remove_tlb_entry(tlb, ptep, address);
> >  		if (huge_pte_dirty(pte))
> >  			set_page_dirty(page);
> @@ -4020,7 +4020,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
> >  			continue;
> >  		}
> >  		if (!huge_pte_none(pte)) {
> > -			pte = huge_ptep_get_and_clear(mm, address, ptep);
> > +			pte = huge_ptep_get_and_clear(vma, address, ptep);
> >  			pte = pte_mkhuge(huge_pte_modify(pte, newprot));
> >  			pte = arch_make_huge_pte(pte, vma, NULL, 0);
> >  			set_huge_pte_at(mm, address, ptep, pte);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
  2016-11-10 19:36     ` Benjamin Herrenschmidt
@ 2016-11-11  1:38       ` Aneesh Kumar K.V
  -1 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-11  1:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Thu, 2016-11-10 at 14:59 +0530, Aneesh Kumar K.V wrote:
>> This help us to find the hugetlb page size which we need ot use on some
>> archs like ppc64 for tlbflush. This also make the interface consistent
>> with other hugetlb functions
>
> What about my requested simpler approach ?

Still working on the changes.

>
> For normal (non-huge) pages, we already know the size.
>
> For huge pages, can't we encode in the top SW bits of the PTE the
> page size that we obtain from set_pte_at ?
>
> That would be a lot less churn and avoid touching all these archs...
> especially since the current DD1 workaround is horrible and I want
> the fix to be backported, so something simpler and contained in
> arch/powerpc feels more suitable.
>

My take as of now is even though the modification lines will be less, it
is going to be much more difficult to follow and backport. I will try to
do a patch to show the complexity and we can decide which approach is
simpler.

-aneesh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg
@ 2016-11-11  1:38       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 12+ messages in thread
From: Aneesh Kumar K.V @ 2016-11-11  1:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, paulus, mpe, akpm; +Cc: linuxppc-dev, linux-mm

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Thu, 2016-11-10 at 14:59 +0530, Aneesh Kumar K.V wrote:
>> This help us to find the hugetlb page size which we need ot use on some
>> archs like ppc64 for tlbflush. This also make the interface consistent
>> with other hugetlb functions
>
> What about my requested simpler approach ?

Still working on the changes.

>
> For normal (non-huge) pages, we already know the size.
>
> For huge pages, can't we encode in the top SW bits of the PTE the
> page size that we obtain from set_pte_at ?
>
> That would be a lot less churn and avoid touching all these archs...
> especially since the current DD1 workaround is horrible and I want
> the fix to be backported, so something simpler and contained in
> arch/powerpc feels more suitable.
>

My take as of now is even though the modification lines will be less, it
is going to be much more difficult to follow and backport. I will try to
do a patch to show the complexity and we can decide which approach is
simpler.

-aneesh

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-11-11  1:39 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-10  9:29 [PATCH 1/4] powerpc/mm: update ptep_set_access_flag to not do full mm tlb flush Aneesh Kumar K.V
2016-11-10  9:29 ` Aneesh Kumar K.V
2016-11-10  9:29 ` [PATCH 2/4] powerpc/mm: Rename hugetlb-radix.h to hugetlb.h Aneesh Kumar K.V
2016-11-10  9:29   ` Aneesh Kumar K.V
2016-11-10  9:29 ` [PATCH 3/4] hugetlb: Change the function prototype to take vma_area_struct as arg Aneesh Kumar K.V
2016-11-10  9:29   ` Aneesh Kumar K.V
2016-11-10 19:36   ` Benjamin Herrenschmidt
2016-11-10 19:36     ` Benjamin Herrenschmidt
2016-11-11  1:38     ` Aneesh Kumar K.V
2016-11-11  1:38       ` Aneesh Kumar K.V
2016-11-10  9:29 ` [PATCH 4/4] powerpc/mm: update pte_update to not do full mm tlb flush Aneesh Kumar K.V
2016-11-10  9:29   ` Aneesh Kumar K.V

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.