summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-11-13 05:39:58 +0000
committeralc <alc@FreeBSD.org>2002-11-13 05:39:58 +0000
commitc02d224c79a209121012072dc916c2d61ce8c1e5 (patch)
treee422808e35d14010cfbd0e3bec778fcc4bba8771 /sys/vm
parent51b18a9ea395df565a980577302fe8bc0f24ab8c (diff)
downloadFreeBSD-src-c02d224c79a209121012072dc916c2d61ce8c1e5.zip
FreeBSD-src-c02d224c79a209121012072dc916c2d61ce8c1e5.tar.gz
Move pmap_collect() out of the machine-dependent code, rename it
to reflect its new location, and add page queue and flag locking. Notes: (1) alpha, i386, and ia64 had identical implementations of pmap_collect() in terms of machine-independent interfaces; (2) sparc64 doesn't require it; (3) powerpc had it as a TODO.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/pmap.h3
-rw-r--r--sys/vm/vm_pageout.c32
2 files changed, 33 insertions, 2 deletions
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h
index 1511e4a..38bde18 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -89,13 +89,14 @@ typedef struct pmap_statistics *pmap_statistics_t;
struct proc;
struct thread;
+extern int pmap_pagedaemon_waken;
+
#ifdef __alpha__
void pmap_page_is_free(vm_page_t m);
#endif
void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
void pmap_clear_modify(vm_page_t m);
void pmap_clear_reference(vm_page_t m);
-void pmap_collect(void);
void pmap_copy(pmap_t, pmap_t, vm_offset_t, vm_size_t, vm_offset_t);
void pmap_copy_page(vm_page_t, vm_page_t);
void pmap_enter(pmap_t, vm_offset_t, vm_page_t, vm_prot_t,
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 00569a0..db27af9 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -109,6 +109,7 @@
/* the kernel process "vm_pageout"*/
static void vm_pageout(void);
static int vm_pageout_clean(vm_page_t);
+static void vm_pageout_pmap_collect(void);
static void vm_pageout_scan(int pass);
static int vm_pageout_free_page_calc(vm_size_t count);
struct proc *pageproc;
@@ -626,6 +627,35 @@ vm_pageout_page_free(vm_page_t m) {
}
/*
+ * This routine is very drastic, but can save the system
+ * in a pinch.
+ */
+static void
+vm_pageout_pmap_collect(void)
+{
+ int i;
+ vm_page_t m;
+ static int warningdone;
+
+ if (pmap_pagedaemon_waken == 0)
+ return;
+ if (warningdone < 5) {
+ printf("collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
+ warningdone++;
+ }
+ vm_page_lock_queues();
+ for (i = 0; i < vm_page_array_size; i++) {
+ m = &vm_page_array[i];
+ if (m->wire_count || m->hold_count || m->busy ||
+ (m->flags & (PG_BUSY | PG_UNMANAGED)))
+ continue;
+ pmap_remove_all(m);
+ }
+ vm_page_unlock_queues();
+ pmap_pagedaemon_waken = 0;
+}
+
+/*
* vm_pageout_scan does the dirty work for the pageout daemon.
*/
static void
@@ -650,7 +680,7 @@ vm_pageout_scan(int pass)
/*
* Do whatever cleanup that the pmap code can.
*/
- pmap_collect();
+ vm_pageout_pmap_collect();
uma_reclaim();
addl_page_shortage_init = vm_pageout_deficit;
OpenPOWER on IntegriCloud