浏览代码

[PATCH] ppc64: More hugepage fixes

My previous patch fixing invalidation of huge PTEs wasn't good enough, we
still had an issue if a PTE invalidation batch contained both small and
large pages.  This patch fixes this by making sure the batch is flushed if
the page size fed to it changes.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Benjamin Herrenschmidt 19 年之前
父节点
当前提交
0f9578b70a
共有 3 个文件被更改,包括 6 次插入4 次删除
  1. 2 3
      arch/ppc64/mm/hash_native.c
  2. 3 1
      arch/ppc64/mm/tlb.c
  3. 1 0
      include/asm-ppc64/tlbflush.h

+ 2 - 3
arch/ppc64/mm/hash_native.c

@@ -343,7 +343,7 @@ static void native_flush_hash_range(unsigned long context,
 	hpte_t *hptep;
 	unsigned long hpte_v;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-	unsigned long large;
+	unsigned long large = batch->large;
 
 	local_irq_save(flags);
 
@@ -356,7 +356,6 @@ static void native_flush_hash_range(unsigned long context,
 
 		va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
 		batch->vaddr[j] = va;
-		large = pte_huge(batch->pte[i]);
 		if (large)
 			vpn = va >> HPAGE_SHIFT;
 		else
@@ -406,7 +405,7 @@ static void native_flush_hash_range(unsigned long context,
 		asm volatile("ptesync":::"memory");
 
 		for (i = 0; i < j; i++)
-			__tlbie(batch->vaddr[i], 0);
+			__tlbie(batch->vaddr[i], large);
 
 		asm volatile("eieio; tlbsync; ptesync":::"memory");
 

+ 3 - 1
arch/ppc64/mm/tlb.c

@@ -143,7 +143,8 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
 	 * up scanning and resetting referenced bits then our batch context
 	 * will change mid stream.
 	 */
-	if (unlikely(i != 0 && context != batch->context)) {
+	if (i != 0 && (context != batch->context ||
+		       batch->large != pte_huge(pte))) {
 		flush_tlb_pending();
 		i = 0;
 	}
@@ -151,6 +152,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
 	if (i == 0) {
 		batch->context = context;
 		batch->mm = mm;
+		batch->large = pte_huge(pte);
 	}
 	batch->pte[i] = __pte(pte);
 	batch->addr[i] = addr;

+ 1 - 0
include/asm-ppc64/tlbflush.h

@@ -25,6 +25,7 @@ struct ppc64_tlb_batch {
 	pte_t pte[PPC64_TLB_BATCH_NR];
 	unsigned long addr[PPC64_TLB_BATCH_NR];
 	unsigned long vaddr[PPC64_TLB_BATCH_NR];
+	unsigned int large;
 };
 DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);