ARM64: kernel oops in 4.4-rc4+
Catalin Marinas
catalin.marinas at arm.com
Tue Dec 8 04:06:26 PST 2015
On Tue, Dec 08, 2015 at 10:51:52AM +0000, Will Deacon wrote:
> On Tue, Dec 08, 2015 at 10:30:13AM +0000, Will Deacon wrote:
> > On Tue, Dec 08, 2015 at 02:30:33PM +0800, Ming Lei wrote:
> > > The attached kernel oops can be triggered immediately after
> > > running the following command on APM Mustang:
> > >
> > > $stress-ng --all 8 -t 10m
> > >
> > > [1] kernel oops log
> > > stress-ng: info: [5220] 5 failures reached, aborting stress process
> > > [ 265.782659] kernel BUG at ./arch/arm64/include/asm/pgtable.h:282!
> >
> > Yikes, this means we're replacing a writable pte with a clean pte, so
> > there's a potential race w/ hardware DBM.
> >
> > Could you dump pte and *ptep please?
>
> I tried running this on my Juno and pretty quickly saw the OOM killer
> coming in. Perhaps, in your case, pte is a swap entry and its confusing
> the checks (so pte_dirty/pte_young are looking at random bits of the
> file offset)?
It could indeed be that the new pte is swap or file and the check misses
that. The easiest is to move the check inside the if (pte_valid_user(pte))
block:
--------------8<------------------------
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7e074f93f383..12d89ee5ab7f 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -269,17 +269,17 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_val(pte) &= ~PTE_RDONLY;
else
pte_val(pte) |= PTE_RDONLY;
- }
- /*
- * If the existing pte is valid, check for potential race with
- * hardware updates of the pte (ptep_set_access_flags safely changes
- * valid ptes without going through an invalid entry).
- */
- if (IS_ENABLED(CONFIG_DEBUG_VM) && IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
- pte_valid(*ptep)) {
- BUG_ON(!pte_young(pte));
- BUG_ON(pte_write(*ptep) && !pte_dirty(pte));
+ /*
+ * If the existing pte is valid, check for potential race with
+ * hardware updates of the pte (ptep_set_access_flags safely
+ * changes valid ptes without going through an invalid entry).
+ */
+ if (IS_ENABLED(CONFIG_DEBUG_VM) && IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
+ pte_valid(*ptep)) {
+ BUG_ON(!pte_young(pte));
+ BUG_ON(pte_write(*ptep) && !pte_dirty(pte));
+ }
}
set_pte(ptep, pte);
--------------8<------------------------
--
Catalin
More information about the linux-arm-kernel
mailing list