summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_anon.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/uvm/uvm_anon.c')
-rw-r--r--sys/uvm/uvm_anon.c209
1 files changed, 25 insertions, 184 deletions
diff --git a/sys/uvm/uvm_anon.c b/sys/uvm/uvm_anon.c
index 47a8b81caf1..673eddc4c2d 100644
--- a/sys/uvm/uvm_anon.c
+++ b/sys/uvm/uvm_anon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_anon.c,v 1.27 2007/04/13 18:57:49 art Exp $ */
+/* $OpenBSD: uvm_anon.c,v 1.28 2007/06/18 21:51:15 pedro Exp $ */
/* $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $ */
/*
@@ -47,22 +47,7 @@
#include <uvm/uvm.h>
#include <uvm/uvm_swap.h>
-/*
- * anonblock_list: global list of anon blocks,
- * locked by swap_syscall_lock (since we never remove
- * anything from this list and we only add to it via swapctl(2)).
- */
-
-struct uvm_anonblock {
- LIST_ENTRY(uvm_anonblock) list;
- int count;
- struct vm_anon *anons;
-};
-static LIST_HEAD(anonlist, uvm_anonblock) anonblock_list;
-
-
-static boolean_t anon_pagein(struct vm_anon *);
-
+struct pool uvm_anon_pool;
/*
* allocate anons
@@ -70,83 +55,9 @@ static boolean_t anon_pagein(struct vm_anon *);
void
uvm_anon_init()
{
- int nanon = uvmexp.free - (uvmexp.free / 16); /* XXXCDC ??? */
-
- simple_lock_init(&uvm.afreelock);
- LIST_INIT(&anonblock_list);
-
- /*
- * Allocate the initial anons.
- */
- uvm_anon_add(nanon);
-}
-
-/*
- * add some more anons to the free pool. called when we add
- * more swap space.
- *
- * => swap_syscall_lock should be held (protects anonblock_list).
- */
-int
-uvm_anon_add(count)
- int count;
-{
- struct uvm_anonblock *anonblock;
- struct vm_anon *anon;
- int lcv, needed;
-
- simple_lock(&uvm.afreelock);
- uvmexp.nanonneeded += count;
- needed = uvmexp.nanonneeded - uvmexp.nanon;
- simple_unlock(&uvm.afreelock);
-
- if (needed <= 0) {
- return 0;
- }
-
- anon = (void *)uvm_km_alloc(kernel_map, sizeof(*anon) * needed);
-
- /* XXX Should wait for VM to free up. */
- if (anon == NULL) {
- printf("uvm_anon_add: can not allocate %d anons\n", needed);
- panic("uvm_anon_add");
- }
-
- MALLOC(anonblock, void *, sizeof(*anonblock), M_UVMAMAP, M_WAITOK);
-
- anonblock->count = needed;
- anonblock->anons = anon;
- LIST_INSERT_HEAD(&anonblock_list, anonblock, list);
- memset(anon, 0, sizeof(*anon) * needed);
-
- simple_lock(&uvm.afreelock);
- uvmexp.nanon += needed;
- uvmexp.nfreeanon += needed;
- for (lcv = 0; lcv < needed; lcv++) {
- simple_lock_init(&anon->an_lock);
- anon[lcv].u.an_nxt = uvm.afree;
- uvm.afree = &anon[lcv];
- simple_lock_init(&uvm.afree->an_lock);
- }
- simple_unlock(&uvm.afreelock);
- return 0;
-}
-
-/*
- * remove anons from the free pool.
- */
-void
-uvm_anon_remove(count)
- int count;
-{
- /*
- * we never actually free any anons, to avoid allocation overhead.
- * XXX someday we might want to try to free anons.
- */
-
- simple_lock(&uvm.afreelock);
- uvmexp.nanonneeded -= count;
- simple_unlock(&uvm.afreelock);
+ pool_init(&uvm_anon_pool, sizeof(struct vm_anon), 0, 0, 0, "anonpl",
+ &pool_allocator_nointr);
+ pool_sethiwat(&uvm_anon_pool, uvmexp.free / 16);
}
/*
@@ -155,19 +66,17 @@ uvm_anon_remove(count)
struct vm_anon *
uvm_analloc()
{
- struct vm_anon *a;
-
- simple_lock(&uvm.afreelock);
- a = uvm.afree;
- if (a) {
- uvm.afree = a->u.an_nxt;
- uvmexp.nfreeanon--;
- a->an_ref = 1;
- a->an_swslot = 0;
- a->u.an_page = NULL; /* so we can free quickly */
+ struct vm_anon *anon;
+
+ anon = pool_get(&uvm_anon_pool, PR_NOWAIT);
+ if (anon) {
+ simple_lock_init(&anon->an_lock);
+ anon->an_ref = 1;
+ anon->an_page = NULL;
+ anon->an_swslot = 0;
+ simple_lock(&anon->an_lock);
}
- simple_unlock(&uvm.afreelock);
- return(a);
+ return(anon);
}
/*
@@ -190,7 +99,7 @@ uvm_anfree(anon)
* get page
*/
- pg = anon->u.an_page;
+ pg = anon->an_page;
/*
* if there is a resident page and it is loaned, then anon may not
@@ -257,11 +166,10 @@ uvm_anfree(anon)
* now that we've stripped the data areas from the anon, free the anon
* itself!
*/
- simple_lock(&uvm.afreelock);
- anon->u.an_nxt = uvm.afree;
- uvm.afree = anon;
- uvmexp.nfreeanon++;
- simple_unlock(&uvm.afreelock);
+ KASSERT(anon->an_page == NULL);
+ KASSERT(anon->an_swslot == 0);
+
+ pool_put(&uvm_anon_pool, anon);
UVMHIST_LOG(maphist,"<- done!",0,0,0,0);
}
@@ -284,7 +192,7 @@ uvm_anon_dropswap(anon)
uvm_swap_free(anon->an_swslot, 1);
anon->an_swslot = 0;
- if (anon->u.an_page == NULL) {
+ if (anon->an_page == NULL) {
/* this page is no longer only in swap. */
simple_lock(&uvm.swap_data_lock);
uvmexp.swpgonly--;
@@ -325,7 +233,7 @@ uvm_anon_lockloanpg(anon)
* not produce an incorrect result.
*/
- while (((pg = anon->u.an_page) != NULL) && pg->loan_count != 0) {
+ while (((pg = anon->an_page) != NULL) && pg->loan_count != 0) {
/*
* quickly check to see if the page has an object before
@@ -387,73 +295,6 @@ uvm_anon_lockloanpg(anon)
return(pg);
}
-
-
-/*
- * page in every anon that is paged out to a range of swslots.
- *
- * swap_syscall_lock should be held (protects anonblock_list).
- */
-
-boolean_t
-anon_swap_off(startslot, endslot)
- int startslot, endslot;
-{
- struct uvm_anonblock *anonblock;
-
- for (anonblock = LIST_FIRST(&anonblock_list);
- anonblock != NULL;
- anonblock = LIST_NEXT(anonblock, list)) {
- int i;
-
- /*
- * loop thru all the anons in the anonblock,
- * paging in where needed.
- */
-
- for (i = 0; i < anonblock->count; i++) {
- struct vm_anon *anon = &anonblock->anons[i];
- int slot;
-
- /*
- * lock anon to work on it.
- */
-
- simple_lock(&anon->an_lock);
-
- /*
- * is this anon's swap slot in range?
- */
-
- slot = anon->an_swslot;
- if (slot >= startslot && slot < endslot) {
- boolean_t rv;
-
- /*
- * yup, page it in.
- */
-
- /* locked: anon */
- rv = anon_pagein(anon);
- /* unlocked: anon */
-
- if (rv) {
- return rv;
- }
- } else {
-
- /*
- * nope, unlock and proceed.
- */
-
- simple_unlock(&anon->an_lock);
- }
- }
- }
- return FALSE;
-}
-
-
/*
* fetch an anon's page.
*
@@ -461,8 +302,8 @@ anon_swap_off(startslot, endslot)
* => returns TRUE if pagein was aborted due to lack of memory.
*/
-static boolean_t
-anon_pagein(anon)
+boolean_t
+uvm_anon_pagein(anon)
struct vm_anon *anon;
{
struct vm_page *pg;
@@ -504,7 +345,7 @@ anon_pagein(anon)
* mark it as dirty, clear its swslot and un-busy it.
*/
- pg = anon->u.an_page;
+ pg = anon->an_page;
uobj = pg->uobject;
uvm_swap_free(anon->an_swslot, 1);
anon->an_swslot = 0;