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

Reply via email to