From d0aa00e891d3bf34e5273456a080ac9c23ac7229 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 3 Feb 2011 23:25:41 -0800 Subject: [PATCH] kernel - Add options VM_PAGE_DEBUG * Add options VM_PAGE_DEBUG for kernel configs. This requires a full kernel rebuild (if you use the option) and supplies additional information in the vm_page structure to help track down problems. --- sys/conf/options | 1 + sys/vm/vm_contig.c | 8 ++++++-- sys/vm/vm_page.c | 4 ++-- sys/vm/vm_page.h | 23 +++++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/sys/conf/options b/sys/conf/options index ce82ae1863..dfca7dbfe5 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -480,6 +480,7 @@ SOCKBUF_DEBUG opt_global.h PANIC_DEBUG opt_global.h MBUF_DEBUG opt_global.h PMAP_DEBUG opt_global.h +VM_PAGE_DEBUG opt_global.h # Sample system/interrupt PC DEBUG_PCTRACK opt_pctrack.h diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 60c266aa9d..55e6e2e7bf 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -343,12 +343,16 @@ again: m->valid = VM_PAGE_BITS_ALL; if (m->flags & PG_ZERO) vm_page_zero_count--; - /* Don't clear the PG_ZERO flag, we'll need it later. */ - m->flags &= PG_ZERO; KASSERT(m->dirty == 0, ("vm_contig_pg_alloc: page %p was dirty", m)); m->wire_count = 0; m->busy = 0; + + /* + * Clear all flags except PG_ZERO and PG_WANTED. This + * also clears PG_BUSY. + */ + vm_page_flag_clear(m, ~(PG_ZERO|PG_WANTED)); } /* diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index ddb6fa029c..95ceff132d 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1130,11 +1130,11 @@ vm_page_free_toq(vm_page_t m) * Clear the UNMANAGED flag when freeing an unmanaged page. */ if (m->flags & PG_UNMANAGED) { - m->flags &= ~PG_UNMANAGED; + vm_page_flag_clear(m, PG_UNMANAGED); } if (m->hold_count != 0) { - m->flags &= ~PG_ZERO; + vm_page_flag_clear(m, PG_ZERO); m->queue = PQ_HOLD; } else { m->queue = PQ_FREE + m->pc; diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index d73717466d..db8e48d23a 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -184,6 +184,10 @@ struct vm_page { u_char dirty; /* map of dirty DEV_BSIZE chunks */ int ku_pagecnt; /* kmalloc helper */ +#ifdef VM_PAGE_DEBUG + const char *busy_func; + int busy_line; +#endif }; #ifndef __VM_PAGE_T_DEFINED__ @@ -395,6 +399,23 @@ vm_page_flag_clear(vm_page_t m, unsigned int bits) atomic_clear_int(&(m)->flags, bits); } +#ifdef VM_PAGE_DEBUG + +static __inline void +_vm_page_busy(vm_page_t m, const char *func, int lineno) +{ + ASSERT_LWKT_TOKEN_HELD(&vm_token); + KASSERT((m->flags & PG_BUSY) == 0, + ("vm_page_busy: page already busy!!!")); + vm_page_flag_set(m, PG_BUSY); + m->busy_func = func; + m->busy_line = lineno; +} + +#define vm_page_busy(m) _vm_page_busy(m, __func__, __LINE__) + +#else + static __inline void vm_page_busy(vm_page_t m) { @@ -404,6 +425,8 @@ vm_page_busy(vm_page_t m) vm_page_flag_set(m, PG_BUSY); } +#endif + /* * vm_page_flash: * -- 2.41.0