Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64/sparc64 when handing back page table pages ...



details:   https://anonhg.NetBSD.org/src/rev/425fdb876124
branches:  trunk
changeset: 752354:425fdb876124
user:      mrg <mrg%NetBSD.org@localhost>
date:      Wed Feb 24 09:49:36 2010 +0000

description:
when handing back page table pages to UVM, flush them from the dcache
on all CPUs.

idea from skrll@, and makes my disk-based SB2000 stable.

tested on U60, SB2000 and SB2500.

diffstat:

 sys/arch/sparc64/sparc64/cache.h    |   5 ++-
 sys/arch/sparc64/sparc64/ipifuncs.c |  23 ++++++++++++-
 sys/arch/sparc64/sparc64/locore.s   |  61 ++++++++++++++++++++++++++++++++++++-
 sys/arch/sparc64/sparc64/pmap.c     |   6 ++-
 4 files changed, 89 insertions(+), 6 deletions(-)

diffs (181 lines):

diff -r 9096a6406847 -r 425fdb876124 sys/arch/sparc64/sparc64/cache.h
--- a/sys/arch/sparc64/sparc64/cache.h  Wed Feb 24 08:22:58 2010 +0000
+++ b/sys/arch/sparc64/sparc64/cache.h  Wed Feb 24 09:49:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cache.h,v 1.14 2010/02/24 06:05:35 mrg Exp $ */
+/*     $NetBSD: cache.h,v 1.15 2010/02/24 09:49:36 mrg Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -138,8 +138,11 @@
 #ifdef MULTIPROCESSOR
 void smp_tlb_flush_pte(vaddr_t, struct pmap *);
 #define        tlb_flush_pte(va,pm)    smp_tlb_flush_pte(va, pm)
+void smp_dcache_flush_page_all(paddr_t pa);
+#define        dcache_flush_page_all(pa)       smp_dcache_flush_page_all(pa)
 #else
 #define        tlb_flush_pte(va,pm)    sp_tlb_flush_pte(va, (pm)->pm_ctx)
+#define        dcache_flush_page_all(pa)       dcache_flush_page(pa)
 #endif
 
 /* Various cache size/line sizes */
diff -r 9096a6406847 -r 425fdb876124 sys/arch/sparc64/sparc64/ipifuncs.c
--- a/sys/arch/sparc64/sparc64/ipifuncs.c       Wed Feb 24 08:22:58 2010 +0000
+++ b/sys/arch/sparc64/sparc64/ipifuncs.c       Wed Feb 24 09:49:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ipifuncs.c,v 1.33 2010/02/24 06:05:35 mrg Exp $ */
+/*     $NetBSD: ipifuncs.c,v 1.34 2010/02/24 09:49:36 mrg Exp $ */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.33 2010/02/24 06:05:35 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.34 2010/02/24 09:49:36 mrg Exp $");
 
 #include "opt_ddb.h"
 
@@ -71,6 +71,8 @@
 void   sparc64_ipi_pause(void *);
 void   sparc64_ipi_flush_pte_us(void *);
 void   sparc64_ipi_flush_pte_usiii(void *);
+void   sparc64_ipi_dcache_flush_page_us(void *);
+void   sparc64_ipi_dcache_flush_page_usiii(void *);
 
 /*
  * Process cpu stop-self event.
@@ -409,6 +411,23 @@
 }
 
 /*
+ * Make sure this page is flushed from all CPUs.
+ */
+void
+smp_dcache_flush_page_all(paddr_t pa)
+{
+       ipifunc_t func;
+
+       if (CPU_IS_USIII_UP())
+               func = sparc64_ipi_dcache_flush_page_usiii;
+       else
+               func = sparc64_ipi_dcache_flush_page_us;
+
+       sparc64_broadcast_ipi(func, pa, dcache_line_size);
+       dcache_flush_page(pa);
+}
+
+/*
  * Print an error message.
  */
 void
diff -r 9096a6406847 -r 425fdb876124 sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Wed Feb 24 08:22:58 2010 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Wed Feb 24 09:49:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.s,v 1.320 2010/02/24 01:58:53 mrg Exp $ */
+/*     $NetBSD: locore.s,v 1.321 2010/02/24 09:49:36 mrg Exp $ */
 
 /*
  * Copyright (c) 1996-2002 Eduardo Horvath
@@ -9047,6 +9047,65 @@
        IPIEVC_INC(IPI_EVCNT_FPU_FLUSH,%g2,%g3)
        ba,a    ret_from_intr_vector
         nop
+
+/*
+ * IPI handler to drop the current FPU state.
+ * void sparc64_ipi_dcache_flush_page_usiii(paddr_t pa, int line_size)
+ * void sparc64_ipi_dcache_flush_page_us(paddr_t pa, int line_size)
+ *
+ * On entry:
+ *     %g2 = pa
+ *     %g3 = line_size
+ */
+ENTRY(sparc64_ipi_dcache_flush_page_usiii)
+       set     NBPG, %g1
+       add     %g2, %g1, %g1   ! end address
+
+1:
+       stxa    %g0, [%g2] ASI_DCACHE_INVALIDATE
+       add     %g2, %g3, %g2
+       cmp     %g2, %g1
+       bl,pt   %xcc, 1b
+        nop
+
+       sethi   %hi(KERNBASE), %g5
+       flush   %g5
+       membar  #Sync
+       ba,a    ret_from_intr_vector
+        nop
+
+ENTRY(sparc64_ipi_dcache_flush_page_us)
+       mov     -1, %g1         ! Generate mask for tag: bits [29..2]
+       srlx    %g2, 13-2, %g5  ! Tag is PA bits <40:13> in bits <29:2>
+       clr     %g4
+       srl     %g1, 2, %g1     ! Now we have bits <29:0> set
+       set     (2*NBPG), %g7
+       ba,pt   %icc, 1f
+        andn   %g1, 3, %g1     ! Now we have bits <29:2> set
+
+       .align 8
+1:
+       ldxa    [%g4] ASI_DCACHE_TAG, %g6
+       mov     %g4, %g2
+       deccc   32, %g7
+       bl,pn   %icc, 2f
+        inc    32, %g4
+
+       xor     %g6, %g5, %g6
+       andcc   %g6, %g1, %g0
+       bne,pt  %xcc, 1b
+        membar #LoadStore
+
+       stxa    %g0, [%g2] ASI_DCACHE_TAG
+       ba,pt   %icc, 1b
+        membar #StoreLoad
+2:
+
+       sethi   %hi(KERNBASE), %g5
+       flush   %g5
+       membar  #Sync
+       ba,a    ret_from_intr_vector
+        nop
 #endif
 
 /*
diff -r 9096a6406847 -r 425fdb876124 sys/arch/sparc64/sparc64/pmap.c
--- a/sys/arch/sparc64/sparc64/pmap.c   Wed Feb 24 08:22:58 2010 +0000
+++ b/sys/arch/sparc64/sparc64/pmap.c   Wed Feb 24 09:49:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.252 2010/02/24 01:58:53 mrg Exp $   */
+/*     $NetBSD: pmap.c,v 1.253 2010/02/24 09:49:36 mrg Exp $   */
 /*
  *
  * Copyright (C) 1996-1999 Eduardo Horvath.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.252 2010/02/24 01:58:53 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.253 2010/02/24 09:49:36 mrg Exp $");
 
 #undef NO_VCACHE /* Don't forget the locked TLB in dostart */
 #define        HWREF
@@ -1405,6 +1405,7 @@
                nextpg = TAILQ_NEXT(pg, listq.queue);
                TAILQ_REMOVE(&pm->pm_obj.memq, pg, listq.queue);
                KASSERT(pg->mdpage.mdpg_pvh.pv_pmap == NULL);
+               dcache_flush_page_all(VM_PAGE_TO_PHYS(pg));
                uvm_pagefree(pg);
        }
        pmap_free_page((paddr_t)(u_long)pm->pm_segs);
@@ -3385,6 +3386,7 @@
 {
        struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
 
+       dcache_flush_page_all(pa);
        uvm_pagefree(pg);
 }
 



Home | Main Index | Thread Index | Old Index