summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1996-10-12 21:35:25 +0000
committerdyson <dyson@FreeBSD.org>1996-10-12 21:35:25 +0000
commit57b4eae0a1b560daffdf0c095a7bcc36bc137858 (patch)
tree1514d1dde20f9ca659b86662c3565290d775a93e /sys
parent01549fd11d3bc0ad90ac3bf29fa51ab279360b55 (diff)
downloadFreeBSD-src-57b4eae0a1b560daffdf0c095a7bcc36bc137858.zip
FreeBSD-src-57b4eae0a1b560daffdf0c095a7bcc36bc137858.tar.gz
Performance optimizations. One of which was meant to go in before the
previous snap. Specifically, kern_exit and kern_exec now makes a call into the pmap module to do a very fast removal of pages from the address space. Additionally, the pmap module now updates the PG_MAPPED and PG_WRITABLE flags. This is an optional optimization, but helpful on the X86.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/pmap.c163
-rw-r--r--sys/amd64/include/pmap.h4
-rw-r--r--sys/i386/i386/pmap.c163
-rw-r--r--sys/i386/include/pmap.h4
-rw-r--r--sys/kern/kern_exec.c3
-rw-r--r--sys/kern/kern_exit.c7
-rw-r--r--sys/kern/subr_rlist.c8
7 files changed, 103 insertions, 249 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 62d0688..b5d0596 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.123 1996/10/09 19:47:19 bde Exp $
+ * $Id: pmap.c,v 1.124 1996/10/12 20:36:15 bde Exp $
*/
/*
@@ -70,6 +70,9 @@
#include "opt_cpu.h"
+#define PMAP_LOCK 1
+#define PMAP_PVLIST 1
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
@@ -204,9 +207,6 @@ static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
static unsigned * pmap_pte_quick __P((pmap_t pmap, vm_offset_t va));
static vm_page_t pmap_page_alloc __P((vm_object_t object, vm_pindex_t pindex));
static vm_page_t pmap_page_lookup __P((vm_object_t object, vm_pindex_t pindex));
-static PMAP_INLINE void pmap_lock __P((pmap_t pmap));
-static PMAP_INLINE void pmap_unlock __P((pmap_t pmap));
-static void pmap_lock2 __P((pmap_t pmap1, pmap_t pmap2));
static int pmap_unuse_pt __P((pmap_t, vm_offset_t, vm_page_t));
#define PDSTACKMAX 6
@@ -259,7 +259,9 @@ pmap_bootstrap(firstaddr, loadaddr)
kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
kernel_pmap->pm_count = 1;
+#if PMAP_PVLIST
TAILQ_INIT(&kernel_pmap->pm_pvlist);
+#endif
nkpt = NKPT;
/*
@@ -434,58 +436,6 @@ invltlb_2pg( vm_offset_t va1, vm_offset_t va2) {
}
}
-
-static PMAP_INLINE void
-pmap_lock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- while (pmap->pm_flags & PM_FLAG_LOCKED) {
- pmap->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap, PVM - 1, "pmaplk", 0);
- }
- splx(s);
-}
-
-static PMAP_INLINE void
-pmap_unlock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- pmap->pm_flags &= ~PM_FLAG_LOCKED;
- if (pmap->pm_flags & PM_FLAG_WANTED) {
- pmap->pm_flags &= ~PM_FLAG_WANTED;
- wakeup(pmap);
- }
-}
-
-static void
-pmap_lock2(pmap1, pmap2)
-pmap_t pmap1, pmap2;
-{
- int s;
- if (pmap1 == kernel_pmap || pmap2 == kernel_pmap)
- return;
- s = splhigh();
- while ((pmap1->pm_flags | pmap2->pm_flags) & PM_FLAG_LOCKED) {
- while (pmap1->pm_flags & PM_FLAG_LOCKED) {
- pmap1->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap1, PVM - 1, "pmapl1", 0);
- }
- while (pmap2->pm_flags & PM_FLAG_LOCKED) {
- pmap2->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap2, PVM - 1, "pmapl2", 0);
- }
- }
- splx(s);
-}
-
static unsigned *
get_ptbase(pmap)
pmap_t pmap;
@@ -566,15 +516,12 @@ pmap_extract(pmap, va)
vm_offset_t va;
{
vm_offset_t rtval;
- pmap_lock(pmap);
if (pmap && *pmap_pde(pmap, va)) {
unsigned *pte;
pte = get_ptbase(pmap) + i386_btop(va);
rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
- pmap_unlock(pmap);
return rtval;
}
- pmap_unlock(pmap);
return 0;
}
@@ -871,7 +818,9 @@ retry:
pmap->pm_flags = 0;
pmap->pm_count = 1;
pmap->pm_ptphint = NULL;
+#if PMAP_PVLIST
TAILQ_INIT(&pmap->pm_pvlist);
+#endif
}
static int
@@ -1081,10 +1030,11 @@ pmap_release(pmap)
vm_page_t p,n,ptdpg;
vm_object_t object = pmap->pm_pteobj;
+#if defined(DIAGNOSTIC)
if (object->ref_count != 1)
panic("pmap_release: pteobj reference count != 1");
+#endif
- pmap_lock(pmap);
ptdpg = NULL;
retry:
for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
@@ -1336,13 +1286,16 @@ pmap_remove_entry(pmap, ppv, va)
int s;
s = splvm();
+#if PMAP_PVLIST
if (ppv->pv_list_count < pmap->pm_stats.resident_count) {
+#endif
for (pv = TAILQ_FIRST(&ppv->pv_list);
pv;
pv = TAILQ_NEXT(pv, pv_list)) {
if (pmap == pv->pv_pmap && va == pv->pv_va)
break;
}
+#if PMAP_PVLIST
} else {
for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
pv;
@@ -1351,13 +1304,20 @@ pmap_remove_entry(pmap, ppv, va)
break;
}
}
+#endif
rtval = 0;
if (pv) {
rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
--ppv->pv_list_count;
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+ }
+
+#if PMAP_PVLIST
TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
+#endif
free_pv_entry(pv);
}
@@ -1387,7 +1347,9 @@ pmap_insert_entry(pmap, va, mpte, pa)
pv->pv_pmap = pmap;
pv->pv_ptem = mpte;
+#if PMAP_PVLIST
TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+#endif
ppv = pa_to_pvh(pa);
TAILQ_INSERT_TAIL(&ppv->pv_list, pv, pv_list);
@@ -1481,7 +1443,6 @@ pmap_remove(pmap, sva, eva)
if (pmap == NULL)
return;
- pmap_lock(pmap);
/*
* special handling of removing one page. a very
* common operation and easy to short circuit some
@@ -1489,7 +1450,6 @@ pmap_remove(pmap, sva, eva)
*/
if ((sva + PAGE_SIZE) == eva) {
pmap_remove_page(pmap, sva);
- pmap_unlock(pmap);
return;
}
@@ -1545,7 +1505,6 @@ pmap_remove(pmap, sva, eva)
if (anyvalid) {
invltlb();
}
- pmap_unlock(pmap);
}
/*
@@ -1587,7 +1546,6 @@ pmap_remove_all(pa)
s = splvm();
ppv = pa_to_pvh(pa);
while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) {
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
pv->pv_pmap->pm_stats.resident_count--;
@@ -1614,13 +1572,16 @@ pmap_remove_all(pa)
update_needed = 1;
}
+#if PMAP_PVLIST
TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+#endif
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
--ppv->pv_list_count;
pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
- pmap_unlock(pv->pv_pmap);
free_pv_entry(pv);
}
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+
if (update_needed)
invltlb();
@@ -1656,7 +1617,6 @@ pmap_protect(pmap, sva, eva, prot)
return;
}
- pmap_lock(pmap);
anychanged = 0;
ptbase = get_ptbase(pmap);
@@ -1697,7 +1657,6 @@ pmap_protect(pmap, sva, eva, prot)
}
}
}
- pmap_unlock(pmap);
if (anychanged)
invltlb();
}
@@ -1730,7 +1689,6 @@ pmap_enter(pmap, va, pa, prot, wired)
if (pmap == NULL)
return;
- pmap_lock(pmap);
va &= PG_FRAME;
#ifdef PMAP_DIAGNOSTIC
if (va > VM_MAX_KERNEL_ADDRESS)
@@ -1849,7 +1807,6 @@ validate:
if (origpte)
invltlb_1pg(va);
}
- pmap_unlock(pmap);
}
/*
@@ -1981,7 +1938,6 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
return;
}
- pmap_lock(pmap);
if (psize + pindex > object->size)
psize = object->size - pindex;
@@ -2040,7 +1996,6 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
}
}
}
- pmap_unlock(pmap);
return;
}
@@ -2077,7 +2032,6 @@ pmap_prefault(pmap, addra, entry, object)
if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap))
return;
- pmap_lock(pmap);
starta = addra - PFBAK * PAGE_SIZE;
if (starta < entry->start) {
starta = entry->start;
@@ -2132,7 +2086,6 @@ pmap_prefault(pmap, addra, entry, object)
PAGE_WAKEUP(m);
}
}
- pmap_unlock(pmap);
}
/*
@@ -2153,7 +2106,6 @@ pmap_change_wiring(pmap, va, wired)
if (pmap == NULL)
return;
- pmap_lock(pmap);
pte = pmap_pte(pmap, va);
if (wired && !pmap_pte_w(pte))
@@ -2166,7 +2118,6 @@ pmap_change_wiring(pmap, va, wired)
* invalidate TLB.
*/
pmap_pte_set_w(pte, wired);
- pmap_unlock(pmap);
}
@@ -2194,11 +2145,8 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
if (dst_addr != src_addr)
return;
- pmap_lock2(src_pmap, dst_pmap);
src_frame = ((unsigned) src_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
if (src_frame != (((unsigned) PTDpde) & PG_FRAME)) {
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
return;
}
@@ -2268,8 +2216,6 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
++dst_pte;
}
}
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
}
/*
@@ -2402,6 +2348,8 @@ pmap_remove_pages(pmap, sva, eva)
pv_entry_t pv, npv;
int s;
+#if PMAP_PVLIST
+
#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap)) {
printf("warning: pmap_remove_pages called with non-current pmap\n");
@@ -2409,9 +2357,7 @@ pmap_remove_pages(pmap, sva, eva)
}
#endif
- pmap_lock(pmap);
- s = splhigh();
-
+ s = splvm();
for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
pv;
pv = npv) {
@@ -2431,30 +2377,32 @@ pmap_remove_pages(pmap, sva, eva)
ppv = pa_to_pvh(tpte);
- if (tpte) {
- pv->pv_pmap->pm_stats.resident_count--;
- if (tpte & PG_W)
- pv->pv_pmap->pm_stats.wired_count--;
- /*
- * Update the vm_page_t clean and reference bits.
- */
- if (tpte & PG_M) {
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
+ pv->pv_pmap->pm_stats.resident_count--;
+ if (tpte & PG_W)
+ pv->pv_pmap->pm_stats.wired_count--;
+ /*
+ * Update the vm_page_t clean and reference bits.
+ */
+ if (tpte & PG_M) {
+ ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
}
+
npv = TAILQ_NEXT(pv, pv_plist);
TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
--ppv->pv_list_count;
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+ }
pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
free_pv_entry(pv);
}
splx(s);
invltlb();
- pmap_unlock(pmap);
+#endif
}
/*
@@ -2501,18 +2449,11 @@ pmap_testbit(pa, bit)
continue;
}
#endif
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
if (*pte & bit) {
- pmap_unlock(pv->pv_pmap);
splx(s);
return TRUE;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
return (FALSE);
@@ -2563,12 +2504,8 @@ pmap_changebit(pa, bit, setem)
}
#endif
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
+
if (setem) {
*(int *)pte |= bit;
changed = 1;
@@ -2586,7 +2523,6 @@ pmap_changebit(pa, bit, setem)
}
}
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
if (changed)
@@ -2654,18 +2590,11 @@ pmap_is_referenced(vm_offset_t pa)
if (!pmap_track_modified(pv->pv_va))
continue;
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
if ((int) *pte & PG_A) {
- pmap_unlock(pv->pv_pmap);
splx(s);
return TRUE;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
return (FALSE);
@@ -2712,17 +2641,14 @@ pmap_ts_referenced(vm_offset_t pa)
if (!pmap_track_modified(pv->pv_va))
continue;
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
continue;
}
if (*pte & PG_A) {
rtval++;
*pte &= ~PG_A;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
if (rtval) {
@@ -2841,10 +2767,8 @@ pmap_mincore(pmap, addr)
unsigned *ptep, pte;
int val = 0;
- pmap_lock(pmap);
ptep = pmap_pte(pmap, addr);
if (ptep == 0) {
- pmap_unlock(pmap);
return 0;
}
@@ -2877,7 +2801,6 @@ pmap_mincore(pmap, addr)
pmap_is_referenced(pa))
val |= MINCORE_REFERENCED_OTHER;
}
- pmap_unlock(pmap);
return val;
}
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 03e58d5..78e335a 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $Id: pmap.h,v 1.43 1996/09/08 16:57:45 dyson Exp $
+ * $Id: pmap.h,v 1.44 1996/10/12 20:36:04 bde Exp $
*/
#ifndef _MACHINE_PMAP_H_
@@ -198,7 +198,9 @@ typedef struct pv_entry {
pmap_t pv_pmap; /* pmap where mapping lies */
vm_offset_t pv_va; /* virtual address for mapping */
TAILQ_ENTRY(pv_entry) pv_list;
+#if PMAP_PVLIST
TAILQ_ENTRY(pv_entry) pv_plist;
+#endif
vm_page_t pv_ptem; /* VM page for pte */
} *pv_entry_t;
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 62d0688..b5d0596 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.123 1996/10/09 19:47:19 bde Exp $
+ * $Id: pmap.c,v 1.124 1996/10/12 20:36:15 bde Exp $
*/
/*
@@ -70,6 +70,9 @@
#include "opt_cpu.h"
+#define PMAP_LOCK 1
+#define PMAP_PVLIST 1
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
@@ -204,9 +207,6 @@ static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
static unsigned * pmap_pte_quick __P((pmap_t pmap, vm_offset_t va));
static vm_page_t pmap_page_alloc __P((vm_object_t object, vm_pindex_t pindex));
static vm_page_t pmap_page_lookup __P((vm_object_t object, vm_pindex_t pindex));
-static PMAP_INLINE void pmap_lock __P((pmap_t pmap));
-static PMAP_INLINE void pmap_unlock __P((pmap_t pmap));
-static void pmap_lock2 __P((pmap_t pmap1, pmap_t pmap2));
static int pmap_unuse_pt __P((pmap_t, vm_offset_t, vm_page_t));
#define PDSTACKMAX 6
@@ -259,7 +259,9 @@ pmap_bootstrap(firstaddr, loadaddr)
kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
kernel_pmap->pm_count = 1;
+#if PMAP_PVLIST
TAILQ_INIT(&kernel_pmap->pm_pvlist);
+#endif
nkpt = NKPT;
/*
@@ -434,58 +436,6 @@ invltlb_2pg( vm_offset_t va1, vm_offset_t va2) {
}
}
-
-static PMAP_INLINE void
-pmap_lock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- while (pmap->pm_flags & PM_FLAG_LOCKED) {
- pmap->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap, PVM - 1, "pmaplk", 0);
- }
- splx(s);
-}
-
-static PMAP_INLINE void
-pmap_unlock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- pmap->pm_flags &= ~PM_FLAG_LOCKED;
- if (pmap->pm_flags & PM_FLAG_WANTED) {
- pmap->pm_flags &= ~PM_FLAG_WANTED;
- wakeup(pmap);
- }
-}
-
-static void
-pmap_lock2(pmap1, pmap2)
-pmap_t pmap1, pmap2;
-{
- int s;
- if (pmap1 == kernel_pmap || pmap2 == kernel_pmap)
- return;
- s = splhigh();
- while ((pmap1->pm_flags | pmap2->pm_flags) & PM_FLAG_LOCKED) {
- while (pmap1->pm_flags & PM_FLAG_LOCKED) {
- pmap1->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap1, PVM - 1, "pmapl1", 0);
- }
- while (pmap2->pm_flags & PM_FLAG_LOCKED) {
- pmap2->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap2, PVM - 1, "pmapl2", 0);
- }
- }
- splx(s);
-}
-
static unsigned *
get_ptbase(pmap)
pmap_t pmap;
@@ -566,15 +516,12 @@ pmap_extract(pmap, va)
vm_offset_t va;
{
vm_offset_t rtval;
- pmap_lock(pmap);
if (pmap && *pmap_pde(pmap, va)) {
unsigned *pte;
pte = get_ptbase(pmap) + i386_btop(va);
rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
- pmap_unlock(pmap);
return rtval;
}
- pmap_unlock(pmap);
return 0;
}
@@ -871,7 +818,9 @@ retry:
pmap->pm_flags = 0;
pmap->pm_count = 1;
pmap->pm_ptphint = NULL;
+#if PMAP_PVLIST
TAILQ_INIT(&pmap->pm_pvlist);
+#endif
}
static int
@@ -1081,10 +1030,11 @@ pmap_release(pmap)
vm_page_t p,n,ptdpg;
vm_object_t object = pmap->pm_pteobj;
+#if defined(DIAGNOSTIC)
if (object->ref_count != 1)
panic("pmap_release: pteobj reference count != 1");
+#endif
- pmap_lock(pmap);
ptdpg = NULL;
retry:
for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
@@ -1336,13 +1286,16 @@ pmap_remove_entry(pmap, ppv, va)
int s;
s = splvm();
+#if PMAP_PVLIST
if (ppv->pv_list_count < pmap->pm_stats.resident_count) {
+#endif
for (pv = TAILQ_FIRST(&ppv->pv_list);
pv;
pv = TAILQ_NEXT(pv, pv_list)) {
if (pmap == pv->pv_pmap && va == pv->pv_va)
break;
}
+#if PMAP_PVLIST
} else {
for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
pv;
@@ -1351,13 +1304,20 @@ pmap_remove_entry(pmap, ppv, va)
break;
}
}
+#endif
rtval = 0;
if (pv) {
rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
--ppv->pv_list_count;
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+ }
+
+#if PMAP_PVLIST
TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
+#endif
free_pv_entry(pv);
}
@@ -1387,7 +1347,9 @@ pmap_insert_entry(pmap, va, mpte, pa)
pv->pv_pmap = pmap;
pv->pv_ptem = mpte;
+#if PMAP_PVLIST
TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+#endif
ppv = pa_to_pvh(pa);
TAILQ_INSERT_TAIL(&ppv->pv_list, pv, pv_list);
@@ -1481,7 +1443,6 @@ pmap_remove(pmap, sva, eva)
if (pmap == NULL)
return;
- pmap_lock(pmap);
/*
* special handling of removing one page. a very
* common operation and easy to short circuit some
@@ -1489,7 +1450,6 @@ pmap_remove(pmap, sva, eva)
*/
if ((sva + PAGE_SIZE) == eva) {
pmap_remove_page(pmap, sva);
- pmap_unlock(pmap);
return;
}
@@ -1545,7 +1505,6 @@ pmap_remove(pmap, sva, eva)
if (anyvalid) {
invltlb();
}
- pmap_unlock(pmap);
}
/*
@@ -1587,7 +1546,6 @@ pmap_remove_all(pa)
s = splvm();
ppv = pa_to_pvh(pa);
while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) {
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
pv->pv_pmap->pm_stats.resident_count--;
@@ -1614,13 +1572,16 @@ pmap_remove_all(pa)
update_needed = 1;
}
+#if PMAP_PVLIST
TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+#endif
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
--ppv->pv_list_count;
pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
- pmap_unlock(pv->pv_pmap);
free_pv_entry(pv);
}
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+
if (update_needed)
invltlb();
@@ -1656,7 +1617,6 @@ pmap_protect(pmap, sva, eva, prot)
return;
}
- pmap_lock(pmap);
anychanged = 0;
ptbase = get_ptbase(pmap);
@@ -1697,7 +1657,6 @@ pmap_protect(pmap, sva, eva, prot)
}
}
}
- pmap_unlock(pmap);
if (anychanged)
invltlb();
}
@@ -1730,7 +1689,6 @@ pmap_enter(pmap, va, pa, prot, wired)
if (pmap == NULL)
return;
- pmap_lock(pmap);
va &= PG_FRAME;
#ifdef PMAP_DIAGNOSTIC
if (va > VM_MAX_KERNEL_ADDRESS)
@@ -1849,7 +1807,6 @@ validate:
if (origpte)
invltlb_1pg(va);
}
- pmap_unlock(pmap);
}
/*
@@ -1981,7 +1938,6 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
return;
}
- pmap_lock(pmap);
if (psize + pindex > object->size)
psize = object->size - pindex;
@@ -2040,7 +1996,6 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
}
}
}
- pmap_unlock(pmap);
return;
}
@@ -2077,7 +2032,6 @@ pmap_prefault(pmap, addra, entry, object)
if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap))
return;
- pmap_lock(pmap);
starta = addra - PFBAK * PAGE_SIZE;
if (starta < entry->start) {
starta = entry->start;
@@ -2132,7 +2086,6 @@ pmap_prefault(pmap, addra, entry, object)
PAGE_WAKEUP(m);
}
}
- pmap_unlock(pmap);
}
/*
@@ -2153,7 +2106,6 @@ pmap_change_wiring(pmap, va, wired)
if (pmap == NULL)
return;
- pmap_lock(pmap);
pte = pmap_pte(pmap, va);
if (wired && !pmap_pte_w(pte))
@@ -2166,7 +2118,6 @@ pmap_change_wiring(pmap, va, wired)
* invalidate TLB.
*/
pmap_pte_set_w(pte, wired);
- pmap_unlock(pmap);
}
@@ -2194,11 +2145,8 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
if (dst_addr != src_addr)
return;
- pmap_lock2(src_pmap, dst_pmap);
src_frame = ((unsigned) src_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
if (src_frame != (((unsigned) PTDpde) & PG_FRAME)) {
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
return;
}
@@ -2268,8 +2216,6 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
++dst_pte;
}
}
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
}
/*
@@ -2402,6 +2348,8 @@ pmap_remove_pages(pmap, sva, eva)
pv_entry_t pv, npv;
int s;
+#if PMAP_PVLIST
+
#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap)) {
printf("warning: pmap_remove_pages called with non-current pmap\n");
@@ -2409,9 +2357,7 @@ pmap_remove_pages(pmap, sva, eva)
}
#endif
- pmap_lock(pmap);
- s = splhigh();
-
+ s = splvm();
for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
pv;
pv = npv) {
@@ -2431,30 +2377,32 @@ pmap_remove_pages(pmap, sva, eva)
ppv = pa_to_pvh(tpte);
- if (tpte) {
- pv->pv_pmap->pm_stats.resident_count--;
- if (tpte & PG_W)
- pv->pv_pmap->pm_stats.wired_count--;
- /*
- * Update the vm_page_t clean and reference bits.
- */
- if (tpte & PG_M) {
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
+ pv->pv_pmap->pm_stats.resident_count--;
+ if (tpte & PG_W)
+ pv->pv_pmap->pm_stats.wired_count--;
+ /*
+ * Update the vm_page_t clean and reference bits.
+ */
+ if (tpte & PG_M) {
+ ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
}
+
npv = TAILQ_NEXT(pv, pv_plist);
TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
--ppv->pv_list_count;
TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
+ }
pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
free_pv_entry(pv);
}
splx(s);
invltlb();
- pmap_unlock(pmap);
+#endif
}
/*
@@ -2501,18 +2449,11 @@ pmap_testbit(pa, bit)
continue;
}
#endif
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
if (*pte & bit) {
- pmap_unlock(pv->pv_pmap);
splx(s);
return TRUE;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
return (FALSE);
@@ -2563,12 +2504,8 @@ pmap_changebit(pa, bit, setem)
}
#endif
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
+
if (setem) {
*(int *)pte |= bit;
changed = 1;
@@ -2586,7 +2523,6 @@ pmap_changebit(pa, bit, setem)
}
}
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
if (changed)
@@ -2654,18 +2590,11 @@ pmap_is_referenced(vm_offset_t pa)
if (!pmap_track_modified(pv->pv_va))
continue;
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
if ((int) *pte & PG_A) {
- pmap_unlock(pv->pv_pmap);
splx(s);
return TRUE;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
return (FALSE);
@@ -2712,17 +2641,14 @@ pmap_ts_referenced(vm_offset_t pa)
if (!pmap_track_modified(pv->pv_va))
continue;
- pmap_lock(pv->pv_pmap);
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
continue;
}
if (*pte & PG_A) {
rtval++;
*pte &= ~PG_A;
}
- pmap_unlock(pv->pv_pmap);
}
splx(s);
if (rtval) {
@@ -2841,10 +2767,8 @@ pmap_mincore(pmap, addr)
unsigned *ptep, pte;
int val = 0;
- pmap_lock(pmap);
ptep = pmap_pte(pmap, addr);
if (ptep == 0) {
- pmap_unlock(pmap);
return 0;
}
@@ -2877,7 +2801,6 @@ pmap_mincore(pmap, addr)
pmap_is_referenced(pa))
val |= MINCORE_REFERENCED_OTHER;
}
- pmap_unlock(pmap);
return val;
}
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 03e58d5..78e335a 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $Id: pmap.h,v 1.43 1996/09/08 16:57:45 dyson Exp $
+ * $Id: pmap.h,v 1.44 1996/10/12 20:36:04 bde Exp $
*/
#ifndef _MACHINE_PMAP_H_
@@ -198,7 +198,9 @@ typedef struct pv_entry {
pmap_t pv_pmap; /* pmap where mapping lies */
vm_offset_t pv_va; /* virtual address for mapping */
TAILQ_ENTRY(pv_entry) pv_list;
+#if PMAP_PVLIST
TAILQ_ENTRY(pv_entry) pv_plist;
+#endif
vm_page_t pv_ptem; /* VM page for pte */
} *pv_entry_t;
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 0fabc69..5a1767d 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_exec.c,v 1.45 1996/07/27 03:23:41 dyson Exp $
+ * $Id: kern_exec.c,v 1.46 1996/07/30 03:08:34 dyson Exp $
*/
#include <sys/param.h>
@@ -368,6 +368,7 @@ exec_new_vmspace(imgp)
if (vmspace->vm_shm)
shmexit(imgp->proc);
vm_map_remove(&vmspace->vm_map, 0, USRSTACK);
+ pmap_remove_pages(&vmspace->vm_pmap, 0, USRSTACK);
/* Allocate a new stack */
error = vm_map_find(&vmspace->vm_map, NULL, 0, (vm_offset_t *)&stack_addr,
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 531c0b2..dd9d6c4 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.39 1996/09/13 09:17:03 bde Exp $
+ * $Id: kern_exit.c,v 1.40 1996/10/04 23:43:12 julian Exp $
*/
#include "opt_ktrace.h"
@@ -182,9 +182,12 @@ exit1(p, rv)
* Can't free the entire vmspace as the kernel stack
* may be mapped within that space also.
*/
- if (vm->vm_refcnt == 1)
+ if (vm->vm_refcnt == 1) {
+ pmap_remove_pages(&vm->vm_pmap, VM_MIN_ADDRESS,
+ VM_MAXUSER_ADDRESS);
(void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
VM_MAXUSER_ADDRESS);
+ }
if (SESS_LEADER(p)) {
register struct session *sp = p->p_session;
diff --git a/sys/kern/subr_rlist.c b/sys/kern/subr_rlist.c
index df4fc7d..4c3aba0 100644
--- a/sys/kern/subr_rlist.c
+++ b/sys/kern/subr_rlist.c
@@ -54,7 +54,7 @@
* functioning of this software, nor does the author assume any responsibility
* for damages incurred with its use.
*
- * $Id: subr_rlist.c,v 1.16 1996/03/02 22:57:45 dyson Exp $
+ * $Id: subr_rlist.c,v 1.17 1996/03/03 21:10:52 dyson Exp $
*/
#include <sys/param.h>
@@ -83,7 +83,7 @@ rlist_malloc()
struct rlist *rl;
int i;
while( rlist_count < RLIST_MIN) {
- int s = splhigh();
+ int s = splvm();
rl = (struct rlist *)kmem_alloc(kernel_map, PAGE_SIZE);
splx(s);
if( !rl)
@@ -122,7 +122,7 @@ rlist_free(rlh, start, end)
struct rlist *prev_rlp = NULL, *cur_rlp = *rlp, *next_rlp = NULL;
int s;
- s = splhigh();
+ s = splvm();
while (rlh->rlh_lock & RLH_LOCKED) {
rlh->rlh_lock |= RLH_DESIRED;
tsleep(rlh, PSWP, "rlistf", 0);
@@ -241,7 +241,7 @@ rlist_alloc (rlh, size, loc)
int s;
register struct rlist *olp = 0;
- s = splhigh();
+ s = splvm();
while (rlh->rlh_lock & RLH_LOCKED) {
rlh->rlh_lock |= RLH_DESIRED;
tsleep(rlh, PSWP, "rlistf", 0);
OpenPOWER on IntegriCloud