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.
This commit is contained in:
parent
582004928e
commit
e77d72e68f
@ -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 @@ sp_tlb_flush_all(void)
|
||||
|
||||
#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;
|
||||
|
@ -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_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 *);
|
||||
void sparc64_ipi_blast_dcache(void *);
|
||||
|
||||
/*
|
||||
* Process cpu stop-self event.
|
||||
@ -427,6 +428,18 @@ smp_dcache_flush_page_all(paddr_t pa)
|
||||
dcache_flush_page(pa);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
@ -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 @@ ENTRY(sp_tlb_flush_all_usiii)
|
||||
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 @@ ENTRY(blast_dcache)
|
||||
#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 @@ ENTRY(blast_dcache)
|
||||
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()
|
||||
|
@ -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 @@ pmap_destroy(struct pmap *pm)
|
||||
return;
|
||||
}
|
||||
DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm));
|
||||
#ifdef MULTIPROCESSOR
|
||||
mutex_enter(&pmap_lock);
|
||||
#ifdef MULTIPROCESSOR
|
||||
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 @@ pmap_remove_all(struct pmap *pm)
|
||||
{
|
||||
#ifdef MULTIPROCESSOR
|
||||
struct cpu_info *ci;
|
||||
sparc64_cpuset_t pmap_cpus_active;
|
||||
#endif
|
||||
|
||||
if (pm == pmap_kernel()) {
|
||||
@ -1870,18 +1871,28 @@ pmap_remove_all(struct pmap *pm)
|
||||
}
|
||||
write_user_windows();
|
||||
pm->pm_refs = 0;
|
||||
#ifdef MULTIPROCESSOR
|
||||
|
||||
mutex_enter(&pmap_lock);
|
||||
#ifdef MULTIPROCESSOR
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user