Replace the page hold queue, PQ_HOLD, by a new page flag, PG_UNHOLDFREE,
because the queue itself serves no purpose. When a held page is freed, inserting the page into the hold queue has the side effect of setting the page's "queue" field to PQ_HOLD. Later, when the page is unheld, it will be freed because the "queue" field is PQ_HOLD. In other words, PQ_HOLD is used as a flag, not a queue. So, this change replaces it with a flag. To accomodate the new page flag, make the page's "flags" field wider and "oflags" field narrower. Reviewed by: kib
This commit is contained in:
parent
5db4d6779f
commit
081a488159
@ -308,7 +308,6 @@ vm_page_startup(vm_offset_t vaddr)
|
||||
TAILQ_INIT(&vm_page_queues[i].pl);
|
||||
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;
|
||||
|
||||
/*
|
||||
* Allocate memory for use when boot strapping the kernel memory
|
||||
@ -540,7 +539,7 @@ vm_page_unhold(vm_page_t mem)
|
||||
vm_page_lock_assert(mem, MA_OWNED);
|
||||
--mem->hold_count;
|
||||
KASSERT(mem->hold_count >= 0, ("vm_page_unhold: hold count < 0!!!"));
|
||||
if (mem->hold_count == 0 && mem->queue == PQ_HOLD)
|
||||
if (mem->hold_count == 0 && (mem->flags & PG_UNHOLDFREE) != 0)
|
||||
vm_page_free_toq(mem);
|
||||
}
|
||||
|
||||
@ -2042,9 +2041,9 @@ vm_page_free_toq(vm_page_t m)
|
||||
panic("vm_page_free: freeing wired page %p", m);
|
||||
if (m->hold_count != 0) {
|
||||
m->flags &= ~PG_ZERO;
|
||||
vm_page_lock_queues();
|
||||
vm_page_enqueue(PQ_HOLD, m);
|
||||
vm_page_unlock_queues();
|
||||
KASSERT((m->flags & PG_UNHOLDFREE) == 0,
|
||||
("vm_page_free: freeing PG_UNHOLDFREE page %p", m));
|
||||
m->flags |= PG_UNHOLDFREE;
|
||||
} else {
|
||||
/*
|
||||
* Restore the default memory attribute to the page.
|
||||
|
@ -145,8 +145,8 @@ struct vm_page {
|
||||
u_short cow; /* page cow mapping count (P) */
|
||||
u_int wire_count; /* wired down maps refs (P) */
|
||||
uint8_t aflags; /* access is atomic */
|
||||
uint8_t flags; /* see below, often immutable after alloc */
|
||||
u_short oflags; /* page flags (O) */
|
||||
uint8_t oflags; /* page VPO_* flags (O) */
|
||||
uint16_t flags; /* page PG_* flags (P) */
|
||||
u_char act_count; /* page usage count (O) */
|
||||
u_char busy; /* page busy count (O) */
|
||||
/* NOTE that these must support one bit per DEV_BSIZE in a page!!! */
|
||||
@ -169,17 +169,16 @@ struct vm_page {
|
||||
* mappings, and such pages are also not on any PQ queue.
|
||||
*
|
||||
*/
|
||||
#define VPO_BUSY 0x0001 /* page is in transit */
|
||||
#define VPO_WANTED 0x0002 /* someone is waiting for page */
|
||||
#define VPO_UNMANAGED 0x0004 /* No PV management for page */
|
||||
#define VPO_SWAPINPROG 0x0200 /* swap I/O in progress on page */
|
||||
#define VPO_NOSYNC 0x0400 /* do not collect for syncer */
|
||||
#define VPO_BUSY 0x01 /* page is in transit */
|
||||
#define VPO_WANTED 0x02 /* someone is waiting for page */
|
||||
#define VPO_UNMANAGED 0x04 /* no PV management for page */
|
||||
#define VPO_SWAPINPROG 0x08 /* swap I/O in progress on page */
|
||||
#define VPO_NOSYNC 0x10 /* do not collect for syncer */
|
||||
|
||||
#define PQ_NONE 255
|
||||
#define PQ_INACTIVE 0
|
||||
#define PQ_ACTIVE 1
|
||||
#define PQ_HOLD 2
|
||||
#define PQ_COUNT 3
|
||||
#define PQ_COUNT 2
|
||||
|
||||
struct vpgqueues {
|
||||
struct pglist pl;
|
||||
@ -263,14 +262,15 @@ extern struct vpglocks pa_lock[];
|
||||
* Page flags. If changed at any other time than page allocation or
|
||||
* freeing, the modification must be protected by the vm_page lock.
|
||||
*/
|
||||
#define PG_CACHED 0x01 /* page is cached */
|
||||
#define PG_FREE 0x02 /* page is free */
|
||||
#define PG_FICTITIOUS 0x04 /* physical page doesn't exist */
|
||||
#define PG_ZERO 0x08 /* page is zeroed */
|
||||
#define PG_MARKER 0x10 /* special queue marker page */
|
||||
#define PG_SLAB 0x20 /* object pointer is actually a slab */
|
||||
#define PG_WINATCFLS 0x40 /* flush dirty page on inactive q */
|
||||
#define PG_NODUMP 0x80 /* don't include this page in a dump */
|
||||
#define PG_CACHED 0x0001 /* page is cached */
|
||||
#define PG_FREE 0x0002 /* page is free */
|
||||
#define PG_FICTITIOUS 0x0004 /* physical page doesn't exist */
|
||||
#define PG_ZERO 0x0008 /* page is zeroed */
|
||||
#define PG_MARKER 0x0010 /* special queue marker page */
|
||||
#define PG_SLAB 0x0020 /* object pointer is actually a slab */
|
||||
#define PG_WINATCFLS 0x0040 /* flush dirty page on inactive q */
|
||||
#define PG_NODUMP 0x0080 /* don't include this page in a dump */
|
||||
#define PG_UNHOLDFREE 0x0100 /* delayed free of a held page */
|
||||
|
||||
/*
|
||||
* Misc constants.
|
||||
|
Loading…
x
Reference in New Issue
Block a user