kernel - Add options VM_PAGE_DEBUG
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 4 Feb 2011 07:25:41 +0000 (23:25 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 4 Feb 2011 07:25:41 +0000 (23:25 -0800)
* 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
sys/vm/vm_contig.c
sys/vm/vm_page.c
sys/vm/vm_page.h

index ce82ae1..dfca7db 100644 (file)
@@ -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
index 60c266a..55e6e2e 100644 (file)
@@ -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));
                }
 
                /*
index ddb6fa0..95ceff1 100644 (file)
@@ -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;
index d737174..db8e48d 100644 (file)
@@ -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:
  *