Message ID | 1369998204-31490-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Accepted, archived |
Commit | 0608d692463598c1d6e826d9dd7283381b4f246c |
Headers | show |
On Fri, May 31, 2013 at 04:33:24PM +0530, Aneesh Kumar K.V wrote: > From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> > > If a hash bucket gets full, we "evict" a more/less random entry from it. > When we do that we don't invalidate the TLB (hpte_remove) because we assume > the old translation is still technically "valid". This implies that when > we are invalidating or updating pte, even if HPTE entry is not valid > we should do a tlb invalidate. > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Has this always been a bug? I assume not. I'm asking because I have a kernel that's crashing and I'm wondering if I might need this commit. cheers
On Sat, 2013-06-01 at 21:19 +1000, Michael Ellerman wrote: > On Fri, May 31, 2013 at 04:33:24PM +0530, Aneesh Kumar K.V wrote: > > From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> > > > > If a hash bucket gets full, we "evict" a more/less random entry from it. > > When we do that we don't invalidate the TLB (hpte_remove) because we assume > > the old translation is still technically "valid". This implies that when > > we are invalidating or updating pte, even if HPTE entry is not valid > > we should do a tlb invalidate. > > > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > > Has this always been a bug? I assume not. > > I'm asking because I have a kernel that's crashing and I'm wondering if > I might need this commit. Bug got introduced in either b1022fbd293564de91596b8775340cf41ad5214c or 7e74c3921ad9610c0b49f28b8fc69f7480505841, the jury is still out on that one :-) It's unlikely to crash the kernel however (it *can*, it's just unlikely). Patch is good to have regardless... Cheers, Ben.
Michael Ellerman <michael@ellerman.id.au> writes: > On Fri, May 31, 2013 at 04:33:24PM +0530, Aneesh Kumar K.V wrote: >> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> >> >> If a hash bucket gets full, we "evict" a more/less random entry from it. >> When we do that we don't invalidate the TLB (hpte_remove) because we assume >> the old translation is still technically "valid". This implies that when >> we are invalidating or updating pte, even if HPTE entry is not valid >> we should do a tlb invalidate. >> >> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > > Has this always been a bug? I assume not. > > I'm asking because I have a kernel that's crashing and I'm wondering if > I might need this commit. Which config are you seeing the issue ? The changes should not impact lpar. Can you share more info on crashes. There is a high chance that any crashes that we are seeing in ppc64 can be the result of THP related changes, because that did touch some subtle areas like tlb flushing,page table format etc. -aneesh
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 6a2aead..4c122c3 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -336,11 +336,18 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, hpte_v = hptep->v; actual_psize = hpte_actual_psize(hptep, psize); + /* + * We need to invalidate the TLB always because hpte_remove doesn't do + * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less + * random entry from it. When we do that we don't invalidate the TLB + * (hpte_remove) because we assume the old translation is still + * technically "valid". + */ if (actual_psize < 0) { - native_unlock_hpte(hptep); - return -1; + actual_psize = psize; + ret = -1; + goto err_out; } - /* Even if we miss, we need to invalidate the TLB */ if (!HPTE_V_COMPARE(hpte_v, want_v)) { DBG_LOW(" -> miss\n"); ret = -1; @@ -350,6 +357,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); } +err_out: native_unlock_hpte(hptep); /* Ensure it is out of the tlb too. */ @@ -409,7 +417,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, hptep = htab_address + slot; actual_psize = hpte_actual_psize(hptep, psize); if (actual_psize < 0) - return; + actual_psize = psize; /* Update the HPTE */ hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | @@ -437,21 +445,27 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, hpte_v = hptep->v; actual_psize = hpte_actual_psize(hptep, psize); + /* + * We need to invalidate the TLB always because hpte_remove doesn't do + * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less + * random entry from it. When we do that we don't invalidate the TLB + * (hpte_remove) because we assume the old translation is still + * technically "valid". + */ if (actual_psize < 0) { + actual_psize = psize; native_unlock_hpte(hptep); - local_irq_restore(flags); - return; + goto err_out; } - /* Even if we miss, we need to invalidate the TLB */ if (!HPTE_V_COMPARE(hpte_v, want_v)) native_unlock_hpte(hptep); else /* Invalidate the hpte. NOTE: this also unlocks it */ hptep->v = 0; +err_out: /* Invalidate the TLB */ tlbie(vpn, psize, actual_psize, ssize, local); - local_irq_restore(flags); }