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:
Alan Cox 2012-10-29 06:15:04 +00:00
parent 5db4d6779f
commit 081a488159
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242300
2 changed files with 21 additions and 22 deletions

View File

@ -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.

View File

@ -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.