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 blast_dcache() SMP friendly:
details: https://anonhg.NetBSD.org/src/rev/203a75bdde7e
branches: trunk
changeset: 752842:203a75bdde7e
user: mrg <mrg%NetBSD.org@localhost>
date: Mon Mar 08 08:59:06 2010 +0000
description:
blast_dcache() SMP friendly:
- blast_dcache() becomes sp_blast_dcache(dcache_size, dcache_line_size)
- new smp_blast_dcache(sparc64_cpuset_t) that blasts the D$ on this cpuset
- sparc64_ipi_blast_dcache() to support the above
- in pmap_remove_all(), when freeing mmu contexts for this pmap, mark
the set of cpus to blast the d$ on as well and convert the
blast_dcache() call into smp_blast_dcache() on the cpus who ran this
pmap, or, sp_blast_dcache(dcache_size, dcache_line_size)
- convert the remaining blast_dcache() in machdep.c to sp_blast_dcache()
- in pmap_destroy()/pmap_remove_all() take the pmap_lock() always since
we assert it is held always.
with these changes, NFS builds on the U60 seem to be stable now, and
the USIII machines also can often complete a single build.sh run now,
diskful or diskless.
reviewed by mlelstv and partially by martin, tested by martin and myself,
with some ideas from chuq as well.
diffstat:
sys/arch/sparc64/sparc64/cache.h | 26 +++++++++++--------
sys/arch/sparc64/sparc64/ipifuncs.c | 17 +++++++++++-
sys/arch/sparc64/sparc64/locore.s | 48 ++++++++++++++++++++++++++----------
sys/arch/sparc64/sparc64/pmap.c | 27 ++++++++++++++------
4 files changed, 84 insertions(+), 34 deletions(-)
diffs (261 lines):
diff -r b6bce5d93e9f -r 203a75bdde7e sys/arch/sparc64/sparc64/cache.h
--- a/sys/arch/sparc64/sparc64/cache.h Mon Mar 08 08:56:03 2010 +0000
+++ b/sys/arch/sparc64/sparc64/cache.h Mon Mar 08 08:59:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cache.h,v 1.16 2010/03/06 08:08:29 mrg Exp $ */
+/* $NetBSD: cache.h,v 1.17 2010/03/08 08:59:06 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -72,10 +72,17 @@
* set-associative -- each bank is 8K. No conflict there.)
*/
+/* Various cache size/line sizes */
+extern int ecache_min_line_size;
+extern int dcache_line_size;
+extern int dcache_size;
+extern int icache_line_size;
+extern int icache_size;
+
/* The following are for I$ and D$ flushes and are in locore.s */
void dcache_flush_page_us(paddr_t); /* flush page from D$ */
void dcache_flush_page_usiii(paddr_t); /* flush page from D$ */
-void blast_dcache(void); /* Clear entire D$ */
+void sp_blast_dcache(int, int); /* Clear entire D$ */
void blast_icache_us(void); /* Clear entire I$ */
void blast_icache_usiii(void); /* Clear entire I$ */
@@ -137,17 +144,14 @@
#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);
+void smp_blast_dcache(sparc64_cpuset_t);
+#define tlb_flush_pte(va,pm ) smp_tlb_flush_pte(va, pm)
#define dcache_flush_page_all(pa) smp_dcache_flush_page_all(pa)
+#define blast_dcache() smp_blast_dcache(cpus_active)
#else
-#define tlb_flush_pte(va,pm) sp_tlb_flush_pte(va, (pm)->pm_ctx[0])
+#define tlb_flush_pte(va,pm) sp_tlb_flush_pte(va, (pm)->pm_ctx[0])
#define dcache_flush_page_all(pa) dcache_flush_page(pa)
+#define blast_dcache() sp_blast_dcache(dcache_size, \
+ dcache_line_size)
#endif
-
-/* Various cache size/line sizes */
-extern int ecache_min_line_size;
-extern int dcache_line_size;
-extern int dcache_size;
-extern int icache_line_size;
-extern int icache_size;
diff -r b6bce5d93e9f -r 203a75bdde7e sys/arch/sparc64/sparc64/ipifuncs.c
--- a/sys/arch/sparc64/sparc64/ipifuncs.c Mon Mar 08 08:56:03 2010 +0000
+++ b/sys/arch/sparc64/sparc64/ipifuncs.c Mon Mar 08 08:59:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.34 2010/02/24 09:49:36 mrg Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.35 2010/03/08 08:59:06 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.34 2010/02/24 09:49:36 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.35 2010/03/08 08:59:06 mrg Exp $");
#include "opt_ddb.h"
@@ -73,6 +73,7 @@
void sparc64_ipi_flush_pte_usiii(void *);
void sparc64_ipi_dcache_flush_page_us(void *);
void sparc64_ipi_dcache_flush_page_usiii(void *);
+void sparc64_ipi_blast_dcache(void *);
/*
* Process cpu stop-self event.
@@ -428,6 +429,18 @@
}
/*
+ * Flush the D$ on this set of CPUs.
+ */
+void
+smp_blast_dcache(sparc64_cpuset_t activecpus)
+{
+
+ sparc64_multicast_ipi(activecpus, sparc64_ipi_blast_dcache,
+ dcache_size, dcache_line_size);
+ sp_blast_dcache(dcache_size, dcache_line_size);
+}
+
+/*
* Print an error message.
*/
void
diff -r b6bce5d93e9f -r 203a75bdde7e sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Mon Mar 08 08:56:03 2010 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Mon Mar 08 08:59:06 2010 +0000
@@ -1,6 +1,7 @@
-/* $NetBSD: locore.s,v 1.325 2010/03/07 01:52:44 mrg Exp $ */
+/* $NetBSD: locore.s,v 1.326 2010/03/08 08:59:06 mrg Exp $ */
/*
+ * Copyright (c) 2006-2010 Matthew R. Green
* Copyright (c) 1996-2002 Eduardo Horvath
* Copyright (c) 1996 Paul Kranenburg
* Copyright (c) 1996
@@ -4918,14 +4919,12 @@
wrpr %o3, %pstate
/*
- * blast_dcache()
+ * sp_blast_dcache(int dcache_size, int dcache_line_size)
*
* Clear out all of D$ regardless of contents
- * Does not modify %o0
- *
*/
.align 8
-ENTRY(blast_dcache)
+ENTRY(sp_blast_dcache)
/*
* We turn off interrupts for the duration to prevent RED exceptions.
*/
@@ -4934,18 +4933,14 @@
#endif
rdpr %pstate, %o3
- sethi %hi(dcache_size), %o1
- ld [%o1 + %lo(dcache_size)], %o1
- sethi %hi(dcache_line_size), %o5
- ld [%o5 + %lo(dcache_line_size)], %o5
- sub %o1, %o5, %o1
+ sub %o0, %o1, %o0
andn %o3, PSTATE_IE, %o4 ! Turn off PSTATE_IE bit
wrpr %o4, 0, %pstate
1:
- stxa %g0, [%o1] ASI_DCACHE_TAG
+ stxa %g0, [%o0] ASI_DCACHE_TAG
membar #Sync
- brnz,pt %o1, 1b
- sub %o1, %o5, %o1
+ brnz,pt %o0, 1b
+ sub %o0, %o1, %o0
sethi %hi(KERNBASE), %o2
flush %o2
@@ -4959,6 +4954,33 @@
wrpr %o3, %pstate
#endif
+#ifdef MULTIPROCESSOR
+/*
+ * void sparc64_ipi_blast_dcache(int dcache_size, int dcache_line_size)
+ *
+ * Clear out all of D$ regardless of contents
+ *
+ * On entry:
+ * %g2 = dcache_size
+ * %g3 = dcache_line_size
+ */
+ .align 8
+ENTRY(sparc64_ipi_blast_dcache)
+ sub %g2, %g3, %g2
+1:
+ stxa %g0, [%g2] ASI_DCACHE_TAG
+ membar #Sync
+ brnz,pt %g2, 1b
+ sub %g2, %g3, %g2
+
+ sethi %hi(KERNBASE), %g5
+ flush %g5
+ membar #Sync
+
+ ba,a ret_from_intr_vector
+ nop
+#endif /* MULTIPROCESSOR */
+
/*
* blast_icache_us()
* blast_icache_usiii()
diff -r b6bce5d93e9f -r 203a75bdde7e sys/arch/sparc64/sparc64/pmap.c
--- a/sys/arch/sparc64/sparc64/pmap.c Mon Mar 08 08:56:03 2010 +0000
+++ b/sys/arch/sparc64/sparc64/pmap.c Mon Mar 08 08:59:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.257 2010/03/06 08:08:30 mrg Exp $ */
+/* $NetBSD: pmap.c,v 1.258 2010/03/08 08:59:06 mrg Exp $ */
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.257 2010/03/06 08:08:30 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.258 2010/03/08 08:59:06 mrg Exp $");
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF
@@ -1365,16 +1365,16 @@
return;
}
DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm));
+ mutex_enter(&pmap_lock);
#ifdef MULTIPROCESSOR
- mutex_enter(&pmap_lock);
for (ci = cpus; ci != NULL; ci = ci->ci_next) {
if (CPUSET_HAS(cpus_active, ci->ci_index))
ctx_free(pm, ci);
}
- mutex_exit(&pmap_lock);
#else
ctx_free(pm, curcpu());
#endif
+ mutex_exit(&pmap_lock);
/* we could be a little smarter and leave pages zeroed */
for (pg = TAILQ_FIRST(&pm->pm_obj.memq); pg != NULL; pg = nextpg) {
@@ -1863,6 +1863,7 @@
{
#ifdef MULTIPROCESSOR
struct cpu_info *ci;
+ sparc64_cpuset_t pmap_cpus_active;
#endif
if (pm == pmap_kernel()) {
@@ -1870,18 +1871,28 @@
}
write_user_windows();
pm->pm_refs = 0;
+
+ mutex_enter(&pmap_lock);
#ifdef MULTIPROCESSOR
- mutex_enter(&pmap_lock);
+ CPUSET_CLEAR(pmap_cpus_active);
for (ci = cpus; ci != NULL; ci = ci->ci_next) {
- if (CPUSET_HAS(cpus_active, ci->ci_index))
+ if (CPUSET_HAS(cpus_active, ci->ci_index)) {
+ if (pm->pm_ctx[ci->ci_index] > 0)
+ CPUSET_ADD(pmap_cpus_active, ci->ci_index);
ctx_free(pm, ci);
+ }
}
- mutex_exit(&pmap_lock);
#else
ctx_free(pm, curcpu());
#endif
+ mutex_exit(&pmap_lock);
+
REMOVE_STAT(flushes);
- blast_dcache();
+#ifdef MULTIPROCESSOR
+ smp_blast_dcache(pmap_cpus_active);
+#else
+ sp_blast_dcache(dcache_size, dcache_line_size);
+#endif
}
/*
Home |
Main Index |
Thread Index |
Old Index