summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-07-05 16:59:56 +0000
committeralc <alc@FreeBSD.org>2004-07-05 16:59:56 +0000
commit53aa64d4e62d2d6746d63cd9bbfa414ebdca0f5b (patch)
tree633719e7f64b41d73d4494c44e81ae7b04ba7bc4 /sys
parentf03dd6e62be000d179ff8cc247e95bbc3e3c8e17 (diff)
downloadFreeBSD-src-53aa64d4e62d2d6746d63cd9bbfa414ebdca0f5b.zip
FreeBSD-src-53aa64d4e62d2d6746d63cd9bbfa414ebdca0f5b.tar.gz
MFamd64/i386
Add partial pmap locking. Tested by: kensmith@
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/alpha/pmap.c19
-rw-r--r--sys/alpha/include/pmap.h14
2 files changed, 33 insertions, 0 deletions
diff --git a/sys/alpha/alpha/pmap.c b/sys/alpha/alpha/pmap.c
index 86b9fc5..c91d372 100644
--- a/sys/alpha/alpha/pmap.c
+++ b/sys/alpha/alpha/pmap.c
@@ -520,6 +520,7 @@ pmap_bootstrap(vm_offset_t ptaddr, u_int maxasn)
/*
* Initialize the kernel pmap (which is statically allocated).
*/
+ PMAP_LOCK_INIT(kernel_pmap);
kernel_pmap->pm_lev1 = Lev1map;
kernel_pmap->pm_active = ~0;
kernel_pmap->pm_asn[alpha_pal_whami()].asn = 0;
@@ -988,6 +989,7 @@ pmap_pinit0(pmap)
{
int i;
+ PMAP_LOCK_INIT(pmap);
pmap->pm_lev1 = Lev1map;
pmap->pm_ptphint = NULL;
pmap->pm_active = 0;
@@ -1012,6 +1014,8 @@ pmap_pinit(pmap)
vm_page_t lev1pg;
int i;
+ PMAP_LOCK_INIT(pmap);
+
/*
* allocate object for the ptes
*/
@@ -1294,6 +1298,7 @@ retry:
mtx_lock_spin(&allpmaps_lock);
LIST_REMOVE(pmap, pm_list);
mtx_unlock_spin(&allpmaps_lock);
+ PMAP_LOCK_DESTROY(pmap);
}
/*
@@ -1618,6 +1623,7 @@ pmap_remove_all(vm_page_t m)
s = splvm();
while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
+ PMAP_LOCK(pv->pv_pmap);
pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
pv->pv_pmap->pm_stats.resident_count--;
@@ -1647,6 +1653,7 @@ pmap_remove_all(vm_page_t m)
TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
m->md.pv_list_count--;
pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
+ PMAP_UNLOCK(pv->pv_pmap);
free_pv_entry(pv);
}
@@ -2033,6 +2040,7 @@ pmap_change_wiring(pmap, va, wired)
if (pmap == NULL)
return;
+ PMAP_LOCK(pmap);
pte = pmap_lev3pte(pmap, va);
if (wired && !pmap_pte_w(pte))
@@ -2045,6 +2053,7 @@ pmap_change_wiring(pmap, va, wired)
* invalidate TLB.
*/
pmap_pte_set_w(pte, wired);
+ PMAP_UNLOCK(pmap);
}
@@ -2186,6 +2195,7 @@ pmap_remove_pages(pmap, sva, eva)
#endif
s = splvm();
+ PMAP_LOCK(pmap);
for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
pv;
pv = npv) {
@@ -2232,6 +2242,7 @@ pmap_remove_pages(pmap, sva, eva)
}
splx(s);
pmap_invalidate_all(pmap);
+ PMAP_UNLOCK(pmap);
}
/*
@@ -2273,6 +2284,7 @@ pmap_changebit(vm_page_t m, int bit, boolean_t setem)
}
#endif
+ PMAP_LOCK(pv->pv_pmap);
pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
changed = 0;
@@ -2288,6 +2300,7 @@ pmap_changebit(vm_page_t m, int bit, boolean_t setem)
}
if (changed)
pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ PMAP_UNLOCK(pv->pv_pmap);
}
if (!setem && bit == (PG_UWE|PG_KWE))
vm_page_flag_clear(m, PG_WRITEABLE);
@@ -2340,6 +2353,7 @@ pmap_ts_referenced(vm_page_t m)
*/
count = 0;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ PMAP_LOCK(pv->pv_pmap);
pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
if (!(*pte & PG_FOR)) {
@@ -2347,6 +2361,7 @@ pmap_ts_referenced(vm_page_t m)
*pte |= PG_FOR | PG_FOE;
pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
+ PMAP_UNLOCK(pv->pv_pmap);
}
return count;
@@ -2416,12 +2431,14 @@ pmap_clear_modify(vm_page_t m)
* Loop over current mappings setting PG_FOW where needed.
*/
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ PMAP_LOCK(pv->pv_pmap);
pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
if (!(*pte & PG_FOW)) {
*pte |= PG_FOW;
pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
+ PMAP_UNLOCK(pv->pv_pmap);
}
}
@@ -2443,12 +2460,14 @@ pmap_clear_reference(vm_page_t m)
* Loop over current mappings setting PG_FOR and PG_FOE where needed.
*/
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ PMAP_LOCK(pv->pv_pmap);
pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
if (!(*pte & (PG_FOR | PG_FOE))) {
*pte |= (PG_FOR | PG_FOE);
pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
+ PMAP_UNLOCK(pv->pv_pmap);
}
}
diff --git a/sys/alpha/include/pmap.h b/sys/alpha/include/pmap.h
index aeeafc2..8c18912 100644
--- a/sys/alpha/include/pmap.h
+++ b/sys/alpha/include/pmap.h
@@ -95,6 +95,8 @@
#ifndef LOCORE
#include <sys/queue.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
typedef alpha_pt_entry_t pt_entry_t;
@@ -165,6 +167,7 @@ struct md_page {
#define ASNGEN_MASK ((1 << ASNGEN_BITS) - 1)
struct pmap {
+ struct mtx pm_mtx;
pt_entry_t *pm_lev1; /* KVA of lev0map */
vm_object_t pm_pteobj; /* Container for pte's */
TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
@@ -183,6 +186,17 @@ typedef struct pmap *pmap_t;
#ifdef _KERNEL
extern struct pmap kernel_pmap_store;
#define kernel_pmap (&kernel_pmap_store)
+
+#define PMAP_LOCK(pmap) mtx_lock(&(pmap)->pm_mtx)
+#define PMAP_LOCK_ASSERT(pmap, type) \
+ mtx_assert(&(pmap)->pm_mtx, (type))
+#define PMAP_LOCK_DESTROY(pmap) mtx_destroy(&(pmap)->pm_mtx)
+#define PMAP_LOCK_INIT(pmap) mtx_init(&(pmap)->pm_mtx, "pmap", \
+ NULL, MTX_DEF)
+#define PMAP_LOCKED(pmap) mtx_owned(&(pmap)->pm_mtx)
+#define PMAP_MTX(pmap) (&(pmap)->pm_mtx)
+#define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx)
+#define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx)
#endif
/*
OpenPOWER on IntegriCloud