Add a page queue, PQ_HOLD, that temporarily owns pages with nonzero hold

count that would otherwise be on one of the free queues.  This eliminates a
panic when broken programs unmap memory that still has pending IO from raw
devices.

Reviewed by:	dillon, alc
This commit is contained in:
Tor Egge 2002-02-19 23:19:30 +00:00
parent 3c442e5104
commit d2760948fe
3 changed files with 11 additions and 4 deletions

View file

@ -413,6 +413,8 @@ vm_page_unhold(vm_page_t mem)
GIANT_REQUIRED;
--mem->hold_count;
KASSERT(mem->hold_count >= 0, ("vm_page_unhold: hold count < 0!!!"));
if (mem->hold_count == 0 && mem->queue == PQ_HOLD)
vm_page_free_toq(mem);
}
/*
@ -1108,8 +1110,7 @@ vm_page_free_toq(vm_page_t m)
s = splvm();
cnt.v_tfree++;
if (m->busy || ((m->queue - m->pc) == PQ_FREE) ||
(m->hold_count != 0)) {
if (m->busy || ((m->queue - m->pc) == PQ_FREE)) {
printf(
"vm_page_free: pindex(%lu), busy(%d), PG_BUSY(%d), hold(%d)\n",
(u_long)m->pindex, m->busy, (m->flags & PG_BUSY) ? 1 : 0,
@ -1178,7 +1179,11 @@ vm_page_free_toq(vm_page_t m)
#endif
}
m->queue = PQ_FREE + m->pc;
if (m->hold_count != 0) {
m->flags &= ~PG_ZERO;
m->queue = PQ_HOLD;
} else
m->queue = PQ_FREE + m->pc;
pq = &vm_page_queues[m->queue];
pq->lcnt++;
++(*pq->cnt);

View file

@ -215,7 +215,8 @@ struct vm_page {
#define PQ_INACTIVE (1 + 1*PQ_L2_SIZE)
#define PQ_ACTIVE (2 + 1*PQ_L2_SIZE)
#define PQ_CACHE (3 + 1*PQ_L2_SIZE)
#define PQ_COUNT (3 + 2*PQ_L2_SIZE)
#define PQ_HOLD (3 + 2*PQ_L2_SIZE)
#define PQ_COUNT (4 + 2*PQ_L2_SIZE)
#else
#define PQ_NONE PQ_COUNT
#define PQ_FREE 0

View file

@ -39,6 +39,7 @@ vm_pageq_init(void)
}
vm_page_queues[PQ_INACTIVE].cnt = &cnt.v_inactive_count;
vm_page_queues[PQ_ACTIVE].cnt = &cnt.v_active_count;
vm_page_queues[PQ_HOLD].cnt = &cnt.v_active_count;
for (i = 0; i < PQ_COUNT; i++) {
TAILQ_INIT(&vm_page_queues[i].pl);