Subject: Re: Qube2 crashes every night
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Andy Ruhl <acruhl@gmail.com>
List: port-cobalt
Date: 11/09/2005 08:28:37
On 11/9/05, Izumi Tsutsui <tsutsui@ceres.dti.ne.jp> wrote:
> In article <78a2305a0511090650j1a268a17o16d7df142e0cec6@mail.gmail.com>
> acruhl@gmail.com wrote:
>
> > > > Does the -current kernel have the same problem?
> > > > ftp://ftp.netbsd.org/pub/NetBSD-daily/HEAD/
> > > I will try this Izumi.
> > Ok. The first test, which is doing ftp, did not crash the machine.
> > I'll see if I can run this kernel for a while and see what happens.
>
> Ok, thanks.
>
> > Is this a known fix that can be applied to release-3?
> > I can test if so.
>
> Could you please try the attached patch for netbsd-3?
> I'll send a pullup request if it actually fixes your problem.
> ---
> Izumi Tsutsui
>
>
> Index: sys/arch/mips/include/cache.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/include/cache.h,v
> retrieving revision 1.7
> diff -u -r1.7 cache.h
> --- sys/arch/mips/include/cache.h       1 Mar 2005 04:23:44 -0000       1=
.7
> +++ sys/arch/mips/include/cache.h       9 Nov 2005 14:59:26 -0000
> @@ -185,8 +185,6 @@
>
>  extern int mips_scache_unified;
>
> -extern u_int mips_sdcache_forceinv;    /* force pmap to invalidate for r=
5ksc */
> -
>  /* TERTIARY CACHE VARIABLES */
>  extern u_int mips_tcache_size;         /* always unified */
>  extern u_int mips_tcache_line_size;
> @@ -201,6 +199,8 @@
>  extern u_int mips_cache_alias_mask;
>  extern u_int mips_cache_prefer_mask;
>
> +extern int mips_cache_virtual_alias;
> +
>  /*
>   * XXX XXX XXX THIS SHOULD NOT EXIST XXX XXX XXX
>   */
> Index: sys/arch/mips/include/pmap.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/include/pmap.h,v
> retrieving revision 1.46
> diff -u -r1.46 pmap.h
> --- sys/arch/mips/include/pmap.h        17 Jan 2005 04:54:14 -0000      1=
.46
> +++ sys/arch/mips/include/pmap.h        9 Nov 2005 14:59:26 -0000
> @@ -180,8 +180,10 @@
>  /*
>   * Alternate mapping hooks for pool pages.  Avoids thrashing the TLB.
>   */
> -#define        PMAP_MAP_POOLPAGE(pa)   MIPS_PHYS_TO_KSEG0((pa))
> -#define        PMAP_UNMAP_POOLPAGE(va) MIPS_KSEG0_TO_PHYS((va))
> +vaddr_t mips_pmap_map_poolpage(paddr_t);
> +paddr_t mips_pmap_unmap_poolpage(vaddr_t);
> +#define        PMAP_MAP_POOLPAGE(pa)   mips_pmap_map_poolpage(pa)
> +#define        PMAP_UNMAP_POOLPAGE(va) mips_pmap_unmap_poolpage(va)
>
>  /*
>   * Other hooks for the pool allocator.
> Index: sys/arch/mips/mips/cache.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/mips/cache.c,v
> retrieving revision 1.26
> diff -u -r1.26 cache.c
> --- sys/arch/mips/mips/cache.c  1 Mar 2005 04:23:44 -0000       1.26
> +++ sys/arch/mips/mips/cache.c  9 Nov 2005 14:59:26 -0000
> @@ -129,8 +129,6 @@
>
>  int mips_scache_unified;
>
> -u_int mips_sdcache_forceinv =3D 0;
> -
>  /* TERTIARY CACHE VARIABLES */
>  u_int mips_tcache_size;                /* always unified */
>  u_int mips_tcache_line_size;
> @@ -154,6 +152,8 @@
>  u_int mips_cache_alias_mask;   /* for virtually-indexed caches */
>  u_int mips_cache_prefer_mask;
>
> +int mips_cache_virtual_alias;
> +
>  struct mips_cache_ops mips_cache_ops;
>
>  #ifdef MIPS1
> @@ -421,6 +421,11 @@
>
>                 mips3_get_cache_config(csizebase);
>
> +               if (mips_picache_size > PAGE_SIZE ||
> +                   mips_pdcache_size > PAGE_SIZE)
> +                       /* no VCE support if there is no L2 cache */
> +                       mips_cache_virtual_alias =3D 1;
> +
>                 switch (mips_picache_line_size) {
>                 case 16:
>                         mips_cache_ops.mco_icache_sync_all =3D
> @@ -494,6 +499,10 @@
>
>                 mips3_get_cache_config(csizebase);
>
> +               if (mips_picache_size > PAGE_SIZE ||
> +                   mips_pdcache_size > PAGE_SIZE)
> +                       mips_cache_virtual_alias =3D 1;
> +
>                 switch (mips_picache_line_size) {
>                 case 32:
>                         mips_cache_ops.mco_icache_sync_all =3D
> @@ -590,6 +599,7 @@
>                     ~(PAGE_SIZE - 1);
>                 mips_cache_prefer_mask =3D
>                     max(mips_pdcache_size, mips_picache_size) - 1;
> +               mips_cache_virtual_alias =3D 1;
>                 /* cache ops */
>                 mips_cache_ops.mco_icache_sync_all =3D
>                     r5900_icache_sync_all_64;
> @@ -619,6 +629,8 @@
>
>                 mips4_get_cache_config(csizebase);
>
> +               /* VCE is handled by hardware */
> +
>                 mips_cache_ops.mco_icache_sync_all =3D
>                     r10k_icache_sync_all;
>                 mips_cache_ops.mco_icache_sync_range =3D
> @@ -670,13 +682,27 @@
>  #if defined(MIPS3) || defined(MIPS4)
>         case MIPS_R4000:
>                 /*
> -                * R4000/R4400 always detects virtual alias as if
> -                * primary cache size is 32KB. Actual primary cache size
> -                * is ignored wrt VCED/VCEI.
> +                * R4000/R4400 detects virtual alias by VCE as if
> +                * its primary cache size were 32KB, because it always
> +                * compares 3 bits of vaddr[14:12] which causes
> +                * primary cache miss and PIdx[2:0] in the secondary
> +                * cache tag regardless of its primary cache size.
> +                * i.e. VCE could happen even if there is no actual
> +                * virtual alias on its 8KB or 16KB primary cache
> +                * which has only 1 or 2 bit valid PIdx in 4KB page.
> +                * Actual primary cache size is ignored wrt VCE
> +                * and virtual aliases are resolved by the VCE hander,
> +                * but it's still worth to avoid unnecessary VCE by
> +                * setting alias mask and prefer mask to 32K, though
> +                * some other possible aliases (maybe caused by KSEG0
> +                * accesses which can't be managed by PMAP_PREFER(9))
> +                * will still be resolved by the VCED/VCEI handler.
>                  */
>                 mips_cache_alias_mask =3D
> -                       (MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1);
> +                   (MIPS3_MAX_PCACHE_SIZE - 1) & ~PAGE_MASK;   /* va[14:=
12] */
>                 mips_cache_prefer_mask =3D MIPS3_MAX_PCACHE_SIZE - 1;
> +
> +               mips_cache_virtual_alias =3D 0;
>                 /* FALLTHROUGH */
>         case MIPS_R4600:
>  #ifdef ENABLE_MIPS_R4700
> Index: sys/arch/mips/mips/mem.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/mips/mem.c,v
> retrieving revision 1.29
> diff -u -r1.29 mem.c
> --- sys/arch/mips/mips/mem.c    7 Aug 2003 16:28:33 -0000       1.29
> +++ sys/arch/mips/mips/mem.c    9 Nov 2005 14:59:27 -0000
> @@ -76,6 +76,9 @@
>   * Memory special file
>   */
>
> +#include "opt_cputype.h"
> +#include "opt_mips_cache.h"
> +
>  #include <sys/cdefs.h>
>  __KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.29 2003/08/07 16:28:33 agc Exp $")=
;
>
> @@ -89,6 +92,8 @@
>
>  #include <machine/cpu.h>
>
> +#include <mips/cache.h>
> +
>  #include <uvm/uvm_extern.h>
>
>  extern paddr_t avail_end;
> @@ -142,6 +147,10 @@
>                                 return (EFAULT);
>                         v +=3D MIPS_KSEG0_START;
>                         error =3D uiomove((void *)v, c, uio);
> +#if defined(MIPS3_PLUS)
> +                       if (mips_cache_virtual_alias)
> +                               mips_dcache_wbinv_range(v, c);
> +#endif
>                         continue;
>
>                 case DEV_KMEM:
> @@ -156,6 +165,10 @@
>                             uio->uio_rw =3D=3D UIO_READ ? B_READ : B_WRIT=
E)))
>                                 return (EFAULT);
>                         error =3D uiomove((void *)v, c, uio);
> +#if defined(MIPS3_PLUS)
> +                       if (mips_cache_virtual_alias)
> +                               mips_dcache_wbinv_range(v, c);
> +#endif
>                         continue;
>
>                 case DEV_NULL:
> Index: sys/arch/mips/mips/pmap.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/mips/pmap.c,v
> retrieving revision 1.157
> diff -u -r1.157 pmap.c
> --- sys/arch/mips/mips/pmap.c   1 Mar 2005 04:23:44 -0000       1.157
> +++ sys/arch/mips/mips/pmap.c   9 Nov 2005 14:59:27 -0000
> @@ -641,10 +641,10 @@
>                          * were being accessed by KSEG0 (cached) addresse=
s and
>                          * may cause cache coherency problems when the pa=
ge
>                          * is reused with KSEG2 (mapped) addresses.  This=
 may
> -                        * cause problems on machines without secondary c=
aches.
> +                        * cause problems on machines without VCED/VCEI.
>                          */
> -                       if (MIPS_HAS_R4K_MMU)
> -                               mips_dcache_wbinv_range((vaddr_t) pte,
> +                       if (mips_cache_virtual_alias)
> +                               mips_dcache_inv_range((vaddr_t)pte,
>                                     PAGE_SIZE);
>  #endif /* MIPS3_PLUS */
>                         uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(p=
te)));
> @@ -1577,6 +1577,11 @@
>  pmap_zero_page(phys)
>         paddr_t phys;
>  {
> +       vaddr_t va;
> +#if defined(MIPS3_PLUS)
> +       pv_entry_t pv;
> +#endif
> +
>  #ifdef DEBUG
>         if (pmapdebug & PDB_FOLLOW)
>                 printf("pmap_zero_page(%lx)\n", (u_long)phys);
> @@ -1585,8 +1590,18 @@
>         if (! (phys < MIPS_MAX_MEM_ADDR))
>                 printf("pmap_zero_page(%lx) nonphys\n", (u_long)phys);
>  #endif
> +       va =3D MIPS_PHYS_TO_KSEG0(phys);
> +
> +#if defined(MIPS3_PLUS)        /* XXX mmu XXX */
> +       if (mips_cache_virtual_alias) {
> +               pv =3D pa_to_pvh(phys);
> +               if ((pv->pv_flags & PV_UNCACHED) =3D=3D 0 &&
> +                   mips_cache_indexof(pv->pv_va) !=3D mips_cache_indexof=
(va))
> +                       mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZ=
E);
> +       }
> +#endif
>
> -       mips_pagezero((caddr_t)MIPS_PHYS_TO_KSEG0(phys));
> +       mips_pagezero((caddr_t)va);
>
>  #if defined(MIPS3_PLUS)        /* XXX mmu XXX */
>         /*
> @@ -1598,9 +1613,8 @@
>          *
>          * XXXJRT This is totally disgusting.
>          */
> -       if (MIPS_HAS_R4K_MMU &&
> -               ( (mips_sdcache_line_size =3D=3D 0) || (mips_sdcache_forc=
einv) ) )
> -               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(phys), NBPG);
> +       if (MIPS_HAS_R4K_MMU)   /* XXX VCED on kernel stack is not allowe=
d */
> +               mips_dcache_wbinv_range(va, PAGE_SIZE);
>  #endif /* MIPS3_PLUS */
>  }
>
> @@ -1636,11 +1650,12 @@
>          * It would probably be better to map the destination as a
>          * write-through no allocate to reduce cache thrash.
>          */
> -       if (MIPS_HAS_R4K_MMU &&
> -               ( (mips_sdcache_line_size =3D=3D 0) || (mips_sdcache_forc=
einv)) ) {
> +       if (mips_cache_virtual_alias) {
>                 /*XXX FIXME Not very sophisticated */
>                 mips_flushcache_allpvh(src);
> -/*             mips_flushcache_allpvh(dst); */
> +#if 0
> +               mips_flushcache_allpvh(dst);
> +#endif
>         }
>  #endif /* MIPS3_PLUS */
>
> @@ -1659,10 +1674,9 @@
>          *
>          * XXXJRT -- This is totally disgusting.
>          */
> -       if (MIPS_HAS_R4K_MMU &&
> -               ( (mips_sdcache_line_size =3D=3D 0) || (mips_sdcache_forc=
einv)) ) {
> -               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), NBPG);
> -               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), NBPG);
> +       if (mips_cache_virtual_alias) {
> +               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), PAGE_SIZ=
E);
> +               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), PAGE_SIZ=
E);
>         }
>  #endif /* MIPS3_PLUS */
>  }
> @@ -1891,7 +1905,7 @@
>                 pv->pv_next =3D NULL;
>         } else {
>  #if defined(MIPS3_PLUS) /* XXX mmu XXX */
> -               if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size =3D=3D 0) =
{
> +               if (mips_cache_virtual_alias) {
>                         /*
>                          * There is at least one other VA mapping this pa=
ge.
>                          * Check if they are cache index compatible.
> @@ -2103,12 +2117,27 @@
>  pmap_pv_page_alloc(struct pool *pp, int flags)
>  {
>         struct vm_page *pg;
> +       paddr_t phys;
> +#if defined(MIPS3_PLUS)
> +       pv_entry_t pv;
> +#endif
> +       vaddr_t va;
>
>         pg =3D uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE);
>         if (pg =3D=3D NULL) {
>                 return NULL;
>         }
> -       return ((void *)MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(pg)));
> +       phys =3D VM_PAGE_TO_PHYS(pg);
> +       va =3D MIPS_PHYS_TO_KSEG0(phys);
> +#if defined(MIPS3_PLUS)
> +       if (mips_cache_virtual_alias) {
> +               pv =3D pa_to_pvh(phys);
> +               if ((pv->pv_flags & PV_UNCACHED) =3D=3D 0 &&
> +                   mips_cache_indexof(pv->pv_va) !=3D mips_cache_indexof=
(va))
> +                       mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZ=
E);
> +       }
> +#endif
> +       return ((void *)va);
>  }
>
>  /*
> @@ -2119,6 +2148,11 @@
>  void
>  pmap_pv_page_free(struct pool *pp, void *v)
>  {
> +
> +#ifdef MIPS3_PLUS
> +       if (mips_cache_virtual_alias)
> +               mips_dcache_inv_range((vaddr_t)v, PAGE_SIZE);
> +#endif
>         uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS((vaddr_t)v)));
>  }
>
> @@ -2162,6 +2196,40 @@
>  }
>  #endif /* MIPS3_PLUS */
>
> +vaddr_t
> +mips_pmap_map_poolpage(paddr_t pa)
> +{
> +       vaddr_t va;
> +#if defined(MIPS3_PLUS)
> +       pv_entry_t pv;
> +#endif
> +
> +       va =3D MIPS_PHYS_TO_KSEG0(pa);
> +#if defined(MIPS3_PLUS)
> +       if (mips_cache_virtual_alias) {
> +               pv =3D pa_to_pvh(pa);
> +               if ((pv->pv_flags & PV_UNCACHED) =3D=3D 0 &&
> +                   mips_cache_indexof(pv->pv_va) !=3D mips_cache_indexof=
(va))
> +                       mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZ=
E);
> +       }
> +#endif
> +       return va;
> +}
> +
> +paddr_t
> +mips_pmap_unmap_poolpage(vaddr_t va)
> +{
> +       paddr_t pa;
> +
> +       pa =3D MIPS_KSEG0_TO_PHYS(va);
> +#if defined(MIPS3_PLUS)
> +       if (mips_cache_virtual_alias) {
> +               mips_dcache_inv_range(va, PAGE_SIZE);
> +       }
> +#endif
> +       return pa;
> +}
> +
>  /******************** page table page management ********************/
>
>  /* TO BE DONE */
> Index: sys/arch/mips/mips/vm_machdep.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /cvsroot/src/sys/arch/mips/mips/vm_machdep.c,v
> retrieving revision 1.105
> diff -u -r1.105 vm_machdep.c
> --- sys/arch/mips/mips/vm_machdep.c     1 Jan 2005 03:25:46 -0000       1=
.105
> +++ sys/arch/mips/mips/vm_machdep.c     9 Nov 2005 14:59:27 -0000
> @@ -131,18 +131,6 @@
>         pt_entry_t *pte;
>         int i, x;
>
> -#ifdef MIPS3_PLUS
> -       /*
> -        * To eliminate virtual aliases created by pmap_zero_page(),
> -        * this cache flush operation is necessary.
> -        * VCED on kernel stack is not allowed.
> -        * XXXJRT Confirm that this is necessry, and/or fix
> -        * XXXJRT pmap_zero_page().
> -        */
> -       if (CPUISMIPS3 && mips_sdcache_line_size)
> -               mips_dcache_wbinv_range((vaddr_t) l2->l_addr, USPACE);
> -#endif
> -
>  #ifdef DIAGNOSTIC
>         /*
>          * If l1 !=3D curlwp && l1 =3D=3D &lwp0, we're creating a kernel =
thread.
>

Thanks Izumi. I will test this when I get time. Hopefully later today.

Andy