On Mon, Oct 20, 2014 at 12:15:42PM +0200, Raphael Graf wrote: > On Thu, October 16, 2014 11:40 pm, Patrick Wildt wrote: > > I do believe that this is a pmap issue. > > > > I just got hands on an Allwinner A20 and suffered the same issues: > > pool_setlowat crashing randomly, same for ahci and so on. > > > > I believe we are not syncing the PTEs correctly. > > > > Here?s the snippet from PTE_SYNC(), but PTE_SYNC_RANGE() has > > the same issue: > > > > #define PTE_SYNC(pte) > > \ > > do { > > \ > > if (PMAP_NEEDS_PTE_SYNC) { \ > > paddr_t pa; \ > > cpu_drain_writebuf(); \ > > cpu_dcache_wb_range((vaddr_t)(pte), sizeof(pt_entry_t));\ > > if (cpu_sdcache_enabled()) { \ > > (void)pmap_extract(pmap_kernel(), (vaddr_t)(pte), &pa); \ > > cpu_sdcache_wb_range((vaddr_t)(pte), (paddr_t)(pa), \ > > sizeof(pt_entry_t)); \ > > }; \ > > cpu_drain_writebuf(); \ > > } \ > > } while (/*CONSTCOND*/0) > > > > I believe that when we change things in the pagetables, we need to make > > sure the tables are synced before we?re going to use them. In our case > > we believe that we are using uncached pagetables, which means that > > every write will directly hit the tables. > > > > But that does not have an affect on the write buffer. The write buffer is > > still > > there and has to be cleared manually. If it isn?t, and something accesses > > an area which was just mapped, then we?re fucked. > > > > Therefore I firmly believe that the cpu_drain_writebuf() call has to be made > > regardless of PMAP_NEEDS_PTE_SYNC and that it has to be called before > > that if-clause. > > > > Doing that fixes my issues. > > > > \Patrick > > > > I think this is correct. With the diff below, my A20 board doesn't panic > anymore. > > I still get a lot of messages like the following though: > pmap_fault_fixup: va 00008000 ftype 1 u pte 7f24f02e
http://permalink.gmane.org/gmane.comp.hardware.netbook.arm.sunxi/3342 It seems Cortex A8/Allwinner A10 allocates cache lines on read and Cortex A7/Allwinner A20 allocates on write. Or rather the A7/A15 have "inner shareable" L2 unlike the A9/A8 which have external "outer shareable" L2 that affects the coherency. The current snapshot has this diff included, and was built on a kernel running it. > > > > Index: sys/arch/arm/include/pmap.h > =================================================================== > RCS file: /cvs/src/sys/arch/arm/include/pmap.h,v > retrieving revision 1.27 > diff -u -p -u -p -r1.27 pmap.h > --- sys/arch/arm/include/pmap.h 7 Oct 2014 10:10:58 -0000 1.27 > +++ sys/arch/arm/include/pmap.h 20 Oct 2014 09:33:14 -0000 > @@ -328,9 +328,9 @@ extern int pmap_needs_pte_sync; > > #define PTE_SYNC(pte) > \ > do { \ > + cpu_drain_writebuf(); \ > if (PMAP_NEEDS_PTE_SYNC) { \ > paddr_t pa; \ > - cpu_drain_writebuf(); \ > cpu_dcache_wb_range((vaddr_t)(pte), sizeof(pt_entry_t));\ > if (cpu_sdcache_enabled()) { \ > (void)pmap_extract(pmap_kernel(), (vaddr_t)(pte), &pa); \ > @@ -343,9 +343,9 @@ do { > \ > > #define PTE_SYNC_RANGE(pte, cnt) > \ > do { \ > + cpu_drain_writebuf(); \ > if (PMAP_NEEDS_PTE_SYNC) { \ > paddr_t pa; \ > - cpu_drain_writebuf(); \ > cpu_dcache_wb_range((vaddr_t)(pte), \ > (cnt) << 2); /* * sizeof(pt_entry_t) */ \ > if (cpu_sdcache_enabled()) { \ >