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()) { \
>