diff options
author | kib <kib@FreeBSD.org> | 2013-08-10 17:36:42 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-08-10 17:36:42 +0000 |
commit | 4675fcfce0ca7178b334ea67fe2d3ab745477a95 (patch) | |
tree | 2ae4177fdf8f77bdbf75571d149fb9e54db96bda /sys/vm/vm_page.h | |
parent | 29e6d17ad1d88a5156b4c44ff927a4ae7be2c279 (diff) | |
download | FreeBSD-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.h | 20 |
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; |