summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-10-22 18:41:32 +0000
committeralc <alc@FreeBSD.org>2003-10-22 18:41:32 +0000
commit794553172bba064691d1e2c2beb861de88f2ec12 (patch)
tree47d61f714782fb39adfa2a86dd96d10ca82461af /sys/vm
parentbac1ff714fbbdb68360b526e681f1a00024f44c4 (diff)
downloadFreeBSD-src-794553172bba064691d1e2c2beb861de88f2ec12.zip
FreeBSD-src-794553172bba064691d1e2c2beb861de88f2ec12.tar.gz
- Retire vm_pageout_page_free(). Instead, use vm_page_select_cache() from
vm_pageout_scan(). Rationale: I don't like leaving a busy page in the cache queue with neither the vm object nor the vm page queues lock held. - Assert that the page is active in vm_pageout_page_stats().
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_page.c2
-rw-r--r--sys/vm/vm_page.h1
-rw-r--r--sys/vm/vm_pageout.c52
3 files changed, 14 insertions, 41 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 58ea6f2..56c1c23 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -698,7 +698,7 @@ vm_page_rename(vm_page_t m, vm_object_t new_object, vm_pindex_t new_pindex)
* This routine must be called at splvm().
* This routine may not block.
*/
-static vm_page_t
+vm_page_t
vm_page_select_cache(int color)
{
vm_page_t m;
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 66631b2..d488bf0 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -368,6 +368,7 @@ void vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t);
vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t);
void vm_page_remove (vm_page_t);
void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t);
+vm_page_t vm_page_select_cache(int);
vm_page_t vm_page_splay(vm_pindex_t, vm_page_t);
vm_offset_t vm_page_startup (vm_offset_t, vm_offset_t, vm_offset_t);
void vm_page_unmanage (vm_page_t);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index f2c9af4..53e6013 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -111,7 +111,6 @@ __FBSDID("$FreeBSD$");
/* the kernel process "vm_pageout"*/
static void vm_pageout(void);
static int vm_pageout_clean(vm_page_t);
-static void vm_pageout_page_free(vm_page_t);
static void vm_pageout_pmap_collect(void);
static void vm_pageout_scan(int pass);
@@ -623,28 +622,6 @@ vm_pageout_map_deactivate_pages(map, desired)
#endif /* !defined(NO_SWAPPING) */
/*
- * Warning! The page queue lock is released and reacquired.
- */
-static void
-vm_pageout_page_free(vm_page_t m)
-{
- vm_object_t object = m->object;
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- vm_page_busy(m);
- vm_page_unlock_queues();
- /*
- * Avoid a lock order reversal. The page must be busy.
- */
- VM_OBJECT_LOCK(object);
- vm_page_lock_queues();
- pmap_remove_all(m);
- vm_page_free(m);
- VM_OBJECT_UNLOCK(object);
- cnt.v_dfree++;
-}
-
-/*
* This routine is very drastic, but can save the system
* in a pinch.
*/
@@ -1112,21 +1089,17 @@ unlock_and_continue:
*/
while (cnt.v_free_count < cnt.v_free_reserved) {
static int cache_rover = 0;
- m = vm_pageq_find(PQ_CACHE, cache_rover, FALSE);
- if (!m)
+
+ if ((m = vm_page_select_cache(cache_rover)) == NULL)
break;
- if ((m->flags & (PG_BUSY|PG_UNMANAGED)) ||
- m->busy ||
- m->hold_count ||
- m->wire_count) {
-#ifdef INVARIANTS
- printf("Warning: busy page %p found in cache\n", m);
-#endif
- vm_page_deactivate(m);
- continue;
- }
- cache_rover = (cache_rover + PQ_PRIME2) & PQ_L2_MASK;
- vm_pageout_page_free(m);
+ cache_rover = (m->pc + PQ_PRIME2) & PQ_L2_MASK;
+ object = m->object;
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+ vm_page_busy(m);
+ pmap_remove_all(m);
+ vm_page_free(m);
+ VM_OBJECT_UNLOCK(object);
+ cnt.v_dfree++;
}
splx(s);
vm_page_unlock_queues();
@@ -1291,9 +1264,8 @@ vm_pageout_page_stats()
while ((m != NULL) && (pcount-- > 0)) {
int actcount;
- if (m->queue != PQ_ACTIVE) {
- break;
- }
+ KASSERT(m->queue == PQ_ACTIVE,
+ ("vm_pageout_page_stats: page %p isn't active", m));
next = TAILQ_NEXT(m, pageq);
/*
OpenPOWER on IntegriCloud