Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc/sparc switch sparc pmap lock to the scheme sp...
details: https://anonhg.NetBSD.org/src/rev/6c46c375bf45
branches: trunk
changeset: 447497:6c46c375bf45
user: mrg <mrg%NetBSD.org@localhost>
date: Sun Jan 13 22:11:11 2019 +0000
description:
switch sparc pmap lock to the scheme sparc64 uses:
- local IPL_NONE mutex for general pmap locking operations, not
kernel lock.
- for pmap_activate()/pmap_deactivate(), switch to using the
existing ctx_lock, and push handling of it into ctx_alloc() the
ctx_free() callers.
fixes easy to trigger deadlocks on systems with >2 cpus. without
this patch i usually hang during boot. with it, i was able to
push the machine hard for over 12 hours.
XXX: pullup-8, and maybe -7.
diffstat:
sys/arch/sparc/sparc/pmap.c | 47 +++++++++++++++++++++++---------------------
1 files changed, 25 insertions(+), 22 deletions(-)
diffs (212 lines):
diff -r 4a963ad406d2 -r 6c46c375bf45 sys/arch/sparc/sparc/pmap.c
--- a/sys/arch/sparc/sparc/pmap.c Sun Jan 13 19:21:27 2019 +0000
+++ b/sys/arch/sparc/sparc/pmap.c Sun Jan 13 22:11:11 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.365 2018/09/03 16:29:27 riastradh Exp $ */
+/* $NetBSD: pmap.c,v 1.366 2019/01/13 22:11:11 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.365 2018/09/03 16:29:27 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.366 2019/01/13 22:11:11 mrg Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -176,8 +176,8 @@
paddr_t vm_last_phys = 0;
psize_t vm_num_phys;
-#define PMAP_LOCK() KERNEL_LOCK(1, NULL)
-#define PMAP_UNLOCK() KERNEL_UNLOCK_ONE(NULL)
+#define PMAP_LOCK() mutex_enter(&pmap_lock)
+#define PMAP_UNLOCK() mutex_exit(&pmap_lock)
/*
* Flags in pvlist.pv_flags. Note that PV_MOD must be 1 and PV_REF must be 2
@@ -347,6 +347,7 @@
int seginval; /* [4/4c] the invalid segment number */
int reginval; /* [4/3mmu] the invalid region number */
+static kmutex_t pmap_lock;
static kmutex_t demap_lock;
static bool lock_available = false; /* demap_lock has been initialized */
@@ -372,15 +373,15 @@
struct pmap *c_pmap; /* pmap (if busy) */
};
-static kmutex_t ctx_lock; /* lock for below */
+static kmutex_t ctx_lock; /* lock for below, and {,de}activate */
union ctxinfo *ctxinfo; /* allocated at in pmap_bootstrap */
union ctxinfo *ctx_freelist; /* context free list */
int ctx_kick; /* allocation rover when none free */
int ctx_kickdir; /* ctx_kick roves both directions */
int ncontext; /* sizeof ctx_freelist */
-void ctx_alloc(struct pmap *);
-void ctx_free(struct pmap *);
+static void ctx_alloc(struct pmap *);
+static void ctx_free(struct pmap *);
/*void * vdumppages; -* 32KB worth of reserved dump pages */
@@ -2121,7 +2122,7 @@
* This routine is only ever called from locore.s just after it has
* saved away the previous process, so there are no active user windows.
*/
-void
+static void
ctx_alloc(struct pmap *pm)
{
union ctxinfo *c;
@@ -2133,6 +2134,8 @@
struct cpu_info *cpi;
#endif
+ KASSERT(mutex_owned(&ctx_lock));
+
/*XXX-GCC!*/gap_start=gap_end=0;
#ifdef DEBUG
if (pm->pm_ctx)
@@ -2145,7 +2148,6 @@
gap_end = pm->pm_gap_end;
}
- mutex_spin_enter(&ctx_lock);
if ((c = ctx_freelist) != NULL) {
ctx_freelist = c->c_nextfree;
cnum = c - ctxinfo;
@@ -2288,13 +2290,12 @@
setcontext4m(cnum);
#endif /* SUN4M || SUN4D */
}
- mutex_spin_exit(&ctx_lock);
}
/*
* Give away a context.
*/
-void
+static void
ctx_free(struct pmap *pm)
{
union ctxinfo *c;
@@ -2303,6 +2304,8 @@
struct cpu_info *cpi;
#endif
+ KASSERT(mutex_owned(&ctx_lock));
+
c = pm->pm_ctx;
ctx = pm->pm_ctxnum;
pm->pm_ctx = NULL;
@@ -2316,8 +2319,6 @@
}
#endif /* SUN4 || SUN4C */
- mutex_spin_enter(&ctx_lock);
-
#if defined(SUN4M) || defined(SUN4D)
if (CPU_HAS_SRMMU) {
CPU_INFO_ITERATOR i;
@@ -2334,7 +2335,6 @@
c->c_nextfree = ctx_freelist;
ctx_freelist = c;
- mutex_spin_exit(&ctx_lock);
}
@@ -3070,6 +3070,7 @@
}
pmap_page_upload();
+ mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM);
mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED);
lock_available = true;
@@ -4392,7 +4393,9 @@
#endif
if ((c = pm->pm_ctx) != NULL) {
+ mutex_spin_enter(&ctx_lock);
ctx_free(pm);
+ mutex_spin_exit(&ctx_lock);
}
#if defined(SUN4M) || defined(SUN4D)
@@ -4662,7 +4665,7 @@
}
ctx = getcontext();
- s = splvm(); /* XXX conservative */
+ s = splvm();
PMAP_LOCK();
for (; va < endva; va = nva) {
/* do one virtual segment at a time */
@@ -6022,7 +6025,7 @@
splx(s);
}
-#if notyet
+#if notyet /* XXXMRG delete */
void pmap_lockmmu(vaddr_t sva, size_t sz);
void
@@ -6286,7 +6289,7 @@
sp = &rp->rg_segmap[vs];
kpreempt_disable();
- s = splvm(); /* XXX way too conservative */
+ s = splvm();
PMAP_LOCK();
if (rp->rg_seg_ptps == NULL) /* enter new region */
@@ -6372,7 +6375,7 @@
vr = VA_VREG(va);
vs = VA_VSEG(va);
rp = &pm->pm_regmap[vr];
- s = splvm(); /* XXX conservative */
+ s = splvm();
PMAP_LOCK();
if (rp->rg_segmap == NULL) {
@@ -7494,14 +7497,14 @@
return;
}
- PMAP_LOCK();
+ mutex_spin_enter(&ctx_lock);
if (pm->pm_ctx == NULL) {
ctx_alloc(pm); /* performs setcontext() */
} else {
setcontext(pm->pm_ctxnum);
}
PMAP_SET_CPUSET(pm, &cpuinfo);
- PMAP_UNLOCK();
+ mutex_spin_exit(&ctx_lock);
}
/*
@@ -7518,7 +7521,7 @@
}
write_user_windows();
- PMAP_LOCK();
+ mutex_spin_enter(&ctx_lock);
if (pm->pm_ctx) {
(*cpuinfo.pure_vcache_flush)();
@@ -7530,7 +7533,7 @@
/* we no longer need broadcast tlb flushes for this pmap. */
PMAP_CLR_CPUSET(pm, &cpuinfo);
- PMAP_UNLOCK();
+ mutex_spin_exit(&ctx_lock);
}
#ifdef DEBUG
Home |
Main Index |
Thread Index |
Old Index