summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.h
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-08-10 17:36:42 +0000
committerkib <kib@FreeBSD.org>2013-08-10 17:36:42 +0000
commit4675fcfce0ca7178b334ea67fe2d3ab745477a95 (patch)
tree2ae4177fdf8f77bdbf75571d149fb9e54db96bda /sys/vm/vm_page.h
parent29e6d17ad1d88a5156b4c44ff927a4ae7be2c279 (diff)
downloadFreeBSD-src-4675fcfce0ca7178b334ea67fe2d3ab745477a95.zip
FreeBSD-src-4675fcfce0ca7178b334ea67fe2d3ab745477a95.tar.gz
Different consumers of the struct vm_page abuse pageq member to keep
additional information, when the page is guaranteed to not belong to a paging queue. Usually, this results in a lot of type casts which make reasoning about the code correctness harder. Sometimes m->object is used instead of pageq, which could cause real and confusing bugs if non-NULL m->object is leaked. See r141955 and r253140 for examples. Change the pageq member into a union containing explicitly-typed members. Use them instead of type-punning or abusing m->object in x86 pmaps, uma and vm_page_alloc_contig(). Requested and reviewed by: alc Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/vm/vm_page.h')
-rw-r--r--sys/vm/vm_page.h20
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 01c4967..43ee04a 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -126,10 +126,19 @@ typedef uint64_t vm_page_bits_t;
#endif
struct vm_page {
- TAILQ_ENTRY(vm_page) pageq; /* page queue or free list (Q) */
- TAILQ_ENTRY(vm_page) listq; /* pages in same object (O) */
-
- vm_object_t object; /* which object am I in (O,P)*/
+ union {
+ TAILQ_ENTRY(vm_page) q; /* page queue or free list (Q) */
+ struct {
+ SLIST_ENTRY(vm_page) ss; /* private slists */
+ void *pv;
+ } s;
+ struct {
+ u_long p;
+ u_long v;
+ } memguard;
+ } plinks;
+ TAILQ_ENTRY(vm_page) listq; /* pages in same object (O) */
+ vm_object_t object; /* which object am I in (O,P) */
vm_pindex_t pindex; /* offset into object (O,P) */
vm_paddr_t phys_addr; /* physical address of page */
struct md_page md; /* machine dependant stuff */
@@ -145,7 +154,7 @@ struct vm_page {
uint16_t flags; /* page PG_* flags (P) */
u_char act_count; /* page usage count (P) */
u_char __pad0; /* unused padding */
- /* NOTE that these must support one bit per DEV_BSIZE in a page!!! */
+ /* NOTE that these must support one bit per DEV_BSIZE in a page */
/* so, on normal X86 kernels, they must be at least 8 bits wide */
vm_page_bits_t valid; /* map of valid DEV_BSIZE chunks (O) */
vm_page_bits_t dirty; /* map of dirty DEV_BSIZE chunks (M) */
@@ -201,6 +210,7 @@ struct vm_page {
#define PQ_COUNT 2
TAILQ_HEAD(pglist, vm_page);
+SLIST_HEAD(spglist, vm_page);
struct vm_pagequeue {
struct mtx pq_mutex;
OpenPOWER on IntegriCloud