summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-06-06 04:32:20 +0000
committeralc <alc@FreeBSD.org>2006-06-06 04:32:20 +0000
commit361dd71e9d336dd4ccd5ba028a930e6ebde9c982 (patch)
tree1ea5da195462097fa692722f1ab47a8741b8fbee /sys
parent12b0f2baa2699306650ffe7d6044253a597550da (diff)
downloadFreeBSD-src-361dd71e9d336dd4ccd5ba028a930e6ebde9c982.zip
FreeBSD-src-361dd71e9d336dd4ccd5ba028a930e6ebde9c982.tar.gz
Add partial pmap locking.
Eliminate the unused allpmaps list. Tested by: cognet@
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/arm/pmap.c23
-rw-r--r--sys/arm/include/pmap.h14
2 files changed, 29 insertions, 8 deletions
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index ed6af4c..57e8c24 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -272,9 +272,6 @@ void (*pmap_zero_page_func)(vm_paddr_t, int, int);
*/
union pmap_cache_state *pmap_cache_state;
-LIST_HEAD(pmaplist, pmap);
-struct pmaplist allpmaps;
-
/* static pt_entry_t *msgbufmap;*/
struct msgbuf *msgbufp = 0;
@@ -1944,6 +1941,8 @@ pmap_pinit0(struct pmap *pmap)
dprintf("pmap_pinit0: pmap = %08x, pm_pdir = %08x\n",
(u_int32_t) pmap, (u_int32_t) pmap->pm_pdir);
bcopy(kernel_pmap, pmap, sizeof(*pmap));
+ bzero(&pmap->pm_mtx, sizeof(pmap->pm_mtx));
+ PMAP_LOCK_INIT(pmap);
}
/*
@@ -2536,11 +2535,10 @@ pmap_bootstrap(vm_offset_t firstaddr, vm_offset_t lastaddr, struct pv_addr *l1pt
cpu_tlb_flushID();
cpu_cpwait();
+ PMAP_LOCK_INIT(kernel_pmap);
kernel_pmap->pm_active = -1;
kernel_pmap->pm_domain = PMAP_DOMAIN_KERNEL;
- LIST_INIT(&allpmaps);
TAILQ_INIT(&kernel_pmap->pm_pvlist);
- LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list);
/*
* Reserve some special page table entries/VA space for temporary
@@ -2601,7 +2599,6 @@ pmap_release(pmap_t pmap)
pmap_idcache_wbinv_all(pmap);
pmap_tlb_flushID(pmap);
cpu_cpwait();
- LIST_REMOVE(pmap, pm_list);
if (vector_page < KERNBASE) {
struct pcb *curpcb = PCPU_GET(curpcb);
pcb = thread0.td_pcb;
@@ -2630,6 +2627,7 @@ pmap_release(pmap_t pmap)
}
pmap_free_l1(pmap);
+ PMAP_LOCK_DESTROY(pmap);
dprintf("pmap_release()\n");
}
@@ -3360,6 +3358,7 @@ pmap_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
u_int oflags;
vm_paddr_t pa;
+ PMAP_ASSERT_LOCKED(pmap);
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
if (va == vector_page) {
pa = systempage.pv_pa;
@@ -3599,11 +3598,13 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
psize = atop(end - start);
m = m_start;
+ PMAP_LOCK(pmap);
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
pmap_enter_locked(pmap, start + ptoa(diff), m, prot &
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
m = TAILQ_NEXT(m, listq);
}
+ PMAP_UNLOCK(pmap);
}
/*
@@ -3620,8 +3621,10 @@ pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
vm_page_t mpte)
{
+ PMAP_LOCK(pmap);
pmap_enter_locked(pmap, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
FALSE);
+ PMAP_UNLOCK(pmap);
return (NULL);
}
@@ -3639,6 +3642,7 @@ pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
pt_entry_t *ptep, pte;
vm_page_t pg;
+ PMAP_LOCK(pmap);
l2b = pmap_get_l2_bucket(pmap, va);
KASSERT(l2b, ("No l2b bucket in pmap_change_wiring"));
ptep = &l2b->l2b_kva[l2pte_index(va)];
@@ -3646,6 +3650,7 @@ pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
pg = PHYS_TO_VM_PAGE(l2pte_pa(pte));
if (pg)
pmap_modify_pv(pg, pmap, va, PVF_WIRED, wired);
+ PMAP_UNLOCK(pmap);
}
@@ -3740,6 +3745,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
l1pd = *pl1pd;
vm_page_lock_queues();
+ PMAP_LOCK(pmap);
if (l1pte_section_p(l1pd)) {
/*
* These should only happen for pmap_kernel()
@@ -3761,6 +3767,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
if (l2 == NULL ||
(ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+ PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
return (NULL);
}
@@ -3769,6 +3776,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
pte = *ptep;
if (pte == 0) {
+ PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
return (NULL);
}
@@ -3787,6 +3795,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
}
}
+ PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
return (m);
}
@@ -3801,10 +3810,10 @@ pmap_pinit(pmap_t pmap)
{
PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap));
+ PMAP_LOCK_INIT(pmap);
pmap_alloc_l1(pmap);
bzero(pmap->pm_l2, sizeof(pmap->pm_l2));
- LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
pmap->pm_count = 1;
pmap->pm_active = 0;
diff --git a/sys/arm/include/pmap.h b/sys/arm/include/pmap.h
index d8e1f2d..0f97246 100644
--- a/sys/arm/include/pmap.h
+++ b/sys/arm/include/pmap.h
@@ -62,6 +62,8 @@
#ifndef LOCORE
#include <sys/queue.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
@@ -136,6 +138,7 @@ struct l2_dtable;
#define L2_SIZE (1 << L2_LOG2)
struct pmap {
+ struct mtx pm_mtx;
u_int8_t pm_domain;
struct l1_ttable *pm_l1;
struct l2_dtable *pm_l2[L2_SIZE];
@@ -144,7 +147,6 @@ struct pmap {
int pm_active; /* active on cpus */
struct pmap_statistics pm_stats; /* pmap statictics */
TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
- LIST_ENTRY(pmap) pm_list; /* List of all pmaps */
};
typedef struct pmap *pmap_t;
@@ -153,6 +155,16 @@ typedef struct pmap *pmap_t;
extern pmap_t kernel_pmap;
#define pmap_kernel() kernel_pmap
+#define PMAP_ASSERT_LOCKED(pmap) \
+ mtx_assert(&(pmap)->pm_mtx, MA_OWNED)
+#define PMAP_LOCK(pmap) mtx_lock(&(pmap)->pm_mtx)
+#define PMAP_LOCK_DESTROY(pmap) mtx_destroy(&(pmap)->pm_mtx)
+#define PMAP_LOCK_INIT(pmap) mtx_init(&(pmap)->pm_mtx, "pmap", \
+ NULL, MTX_DEF | MTX_DUPOK)
+#define PMAP_OWNED(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