summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r--sys/vm/vm_page.c123
1 files changed, 82 insertions, 41 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 2072bf3..6837ecf 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- * $Id: vm_page.c,v 1.86 1998/01/17 09:16:59 dyson Exp $
+ * $Id: vm_page.c,v 1.87 1998/01/22 17:30:41 dyson Exp $
*/
/*
@@ -416,6 +416,12 @@ vm_page_insert(m, object, pindex)
m->object->page_hint = m;
m->object->generation++;
+ if (m->wire_count)
+ object->wire_count++;
+
+ if ((m->queue - m->pc) == PQ_CACHE)
+ object->cache_count++;
+
/*
* And show that the object has one more resident page.
*/
@@ -442,9 +448,25 @@ vm_page_remove(m)
if (!(m->flags & PG_TABLED))
return;
+ if ((m->flags & PG_BUSY) == 0) {
+ panic("vm_page_remove: page not busy");
+ }
+
+ m->flags &= ~PG_BUSY;
+ if (m->flags & PG_WANTED) {
+ m->flags &= ~PG_WANTED;
+ wakeup(m);
+ }
+
if (m->object->page_hint == m)
m->object->page_hint = NULL;
+ if (m->wire_count)
+ m->object->wire_count--;
+
+ if ((m->queue - m->pc) == PQ_CACHE)
+ m->object->cache_count--;
+
/*
* Remove from the object_object/offset hash table
*/
@@ -542,8 +564,11 @@ vm_page_unqueue_nowakeup(m)
pq = &vm_page_queues[queue];
m->queue = PQ_NONE;
TAILQ_REMOVE(pq->pl, m, pageq);
- --(*pq->cnt);
- --(*pq->lcnt);
+ (*pq->cnt)--;
+ (*pq->lcnt)--;
+ if ((queue - m->pc) == PQ_CACHE) {
+ m->object->cache_count--;
+ }
}
}
@@ -560,12 +585,13 @@ vm_page_unqueue(m)
m->queue = PQ_NONE;
pq = &vm_page_queues[queue];
TAILQ_REMOVE(pq->pl, m, pageq);
- --(*pq->cnt);
- --(*pq->lcnt);
+ (*pq->cnt)--;
+ (*pq->lcnt)--;
if ((queue - m->pc) == PQ_CACHE) {
if ((cnt.v_cache_count + cnt.v_free_count) <
(cnt.v_free_reserved + cnt.v_cache_min))
pagedaemon_wakeup();
+ m->object->cache_count--;
}
}
}
@@ -868,16 +894,17 @@ vm_page_alloc(object, pindex, page_req)
queue = m->queue;
qtype = queue - m->pc;
if (qtype == PQ_ZERO)
- --vm_page_zero_count;
+ vm_page_zero_count--;
pq = &vm_page_queues[queue];
TAILQ_REMOVE(pq->pl, m, pageq);
- --(*pq->cnt);
- --(*pq->lcnt);
+ (*pq->cnt)--;
+ (*pq->lcnt)--;
oldobject = NULL;
if (qtype == PQ_ZERO) {
m->flags = PG_ZERO|PG_BUSY;
} else if (qtype == PQ_CACHE) {
oldobject = m->object;
+ m->flags |= PG_BUSY;
vm_page_remove(m);
m->flags = PG_BUSY;
} else {
@@ -953,24 +980,34 @@ vm_page_activate(m)
register vm_page_t m;
{
int s;
+ vm_page_t np;
+ vm_object_t object;
s = splvm();
- if (m->queue == PQ_ACTIVE)
- panic("vm_page_activate: already active");
-
- if ((m->queue - m->pc) == PQ_CACHE)
- cnt.v_reactivated++;
+ if (m->queue != PQ_ACTIVE) {
+ if ((m->queue - m->pc) == PQ_CACHE)
+ cnt.v_reactivated++;
- vm_page_unqueue(m);
+ vm_page_unqueue(m);
- if (m->wire_count == 0) {
- m->queue = PQ_ACTIVE;
- ++(*vm_page_queues[PQ_ACTIVE].lcnt);
- TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
+ if (m->wire_count == 0) {
+ m->queue = PQ_ACTIVE;
+ ++(*vm_page_queues[PQ_ACTIVE].lcnt);
+ TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
+ if (m->act_count < ACT_INIT)
+ m->act_count = ACT_INIT;
+ cnt.v_active_count++;
+ }
+ } else {
if (m->act_count < ACT_INIT)
m->act_count = ACT_INIT;
- cnt.v_active_count++;
}
+
+ object = m->object;
+ TAILQ_REMOVE(&object->memq, m, listq);
+ TAILQ_INSERT_TAIL(&object->memq, m, listq);
+ object->generation++;
+
splx(s);
}
@@ -986,9 +1023,7 @@ vm_page_freechk_and_unqueue(m)
oldobject = m->object;
#if !defined(MAX_PERF)
- if (m->busy ||
- (m->flags & PG_BUSY) ||
- ((m->queue - m->pc) == PQ_FREE) ||
+ if (m->busy || ((m->queue - m->pc) == PQ_FREE) ||
(m->hold_count != 0)) {
printf("vm_page_free: pindex(%ld), busy(%d), PG_BUSY(%d), hold(%d)\n",
m->pindex, m->busy,
@@ -1000,17 +1035,20 @@ vm_page_freechk_and_unqueue(m)
}
#endif
- vm_page_remove(m);
vm_page_unqueue_nowakeup(m);
+ vm_page_remove(m);
+
if ((m->flags & PG_FICTITIOUS) != 0) {
return 0;
}
+
if (m->wire_count != 0) {
if (m->wire_count > 1) {
panic("vm_page_free: invalid wire count (%d), pindex: 0x%x",
m->wire_count, m->pindex);
}
m->wire_count = 0;
+ m->object->wire_count--;
cnt.v_wire_count--;
}
@@ -1147,8 +1185,9 @@ vm_page_wire(m)
vm_page_unqueue(m);
splx(s);
cnt.v_wire_count++;
+ m->object->wire_count++;
}
- ++(*vm_page_queues[PQ_NONE].lcnt);
+ (*vm_page_queues[PQ_NONE].lcnt)++;
m->wire_count++;
m->flags |= PG_MAPPED;
}
@@ -1169,15 +1208,18 @@ vm_page_unwire(m)
s = splvm();
- if (m->wire_count > 0)
+ if (m->wire_count > 0) {
m->wire_count--;
-
- if (m->wire_count == 0) {
- cnt.v_wire_count--;
- TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
- m->queue = PQ_ACTIVE;
- ++(*vm_page_queues[PQ_ACTIVE].lcnt);
- cnt.v_active_count++;
+ if (m->wire_count == 0) {
+ m->object->wire_count--;
+ cnt.v_wire_count--;
+ TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
+ m->queue = PQ_ACTIVE;
+ (*vm_page_queues[PQ_ACTIVE].lcnt)++;
+ cnt.v_active_count++;
+ }
+ } else {
+ panic("vm_page_unwire: invalid wire count: %d\n", m->wire_count);
}
splx(s);
}
@@ -1246,9 +1288,10 @@ vm_page_cache(m)
s = splvm();
vm_page_unqueue_nowakeup(m);
m->queue = PQ_CACHE + m->pc;
- ++(*vm_page_queues[m->queue].lcnt);
+ (*vm_page_queues[m->queue].lcnt)++;
TAILQ_INSERT_TAIL(vm_page_queues[m->queue].pl, m, pageq);
cnt.v_cache_count++;
+ m->object->cache_count++;
vm_page_free_wakeup();
splx(s);
}
@@ -1415,9 +1458,7 @@ again1:
goto again1;
}
}
- if ((m->dirty == 0) &&
- (m->busy == 0) &&
- (m->hold_count == 0))
+ if ((m->dirty == 0) && (m->busy == 0) && (m->hold_count == 0))
vm_page_cache(m);
}
@@ -1449,9 +1490,7 @@ again1:
goto again1;
}
}
- if ((m->dirty == 0) &&
- (m->busy == 0) &&
- (m->hold_count == 0))
+ if ((m->dirty == 0) && (m->busy == 0) && (m->hold_count == 0))
vm_page_cache(m);
}
@@ -1479,11 +1518,13 @@ again1:
vm_page_t m = &pga[i];
pqtype = m->queue - m->pc;
- if (pqtype == PQ_CACHE)
+ if (pqtype == PQ_CACHE) {
+ m->flags |= PG_BUSY;
vm_page_free(m);
+ }
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
- --(*vm_page_queues[m->queue].lcnt);
+ (*vm_page_queues[m->queue].lcnt)--;
cnt.v_free_count--;
m->valid = VM_PAGE_BITS_ALL;
m->flags = 0;
OpenPOWER on IntegriCloud