Author: kib
Date: Thu Apr 23 21:09:47 2009
New Revision: 191439
URL: http://svn.freebsd.org/changeset/base/191439

Log:
  Do not call vm_page_lookup() from the ddb routine, namely from "show
  vmopag" implementation. The vm_page_lookup() code modifies splay tree
  of the object pages, and asserts that object lock is taken. First issue
  could cause kernel data corruption, and second one instantly panics the
  INVARIANTS-enabled kernel.
  
  Take the advantage of the fact that object->memq is ordered by page index,
  and iterate over memq to calculate the runs.
  
  While there, make the code slightly more style-compliant by moving
  variables declarations to the right place.
  
  Discussed with:       jhb, alc
  Reviewed by:  alc
  MFC after:    2 weeks

Modified:
  head/sys/vm/vm_object.c

Modified: head/sys/vm/vm_object.c
==============================================================================
--- head/sys/vm/vm_object.c     Thu Apr 23 20:24:19 2009        (r191438)
+++ head/sys/vm/vm_object.c     Thu Apr 23 21:09:47 2009        (r191439)
@@ -2196,16 +2196,13 @@ vm_object_print(
 DB_SHOW_COMMAND(vmopag, vm_object_print_pages)
 {
        vm_object_t object;
-       int nl = 0;
-       int c;
+       vm_pindex_t fidx;
+       vm_paddr_t pa;
+       vm_page_t m, prev_m;
+       int rcount, nl, c;
 
+       nl = 0;
        TAILQ_FOREACH(object, &vm_object_list, object_list) {
-               vm_pindex_t idx, fidx;
-               vm_pindex_t osize;
-               vm_paddr_t pa = -1;
-               int rcount;
-               vm_page_t m;
-
                db_printf("new object: %p\n", (void *)object);
                if (nl > 18) {
                        c = cngetc();
@@ -2216,12 +2213,12 @@ DB_SHOW_COMMAND(vmopag, vm_object_print_
                nl++;
                rcount = 0;
                fidx = 0;
-               osize = object->size;
-               if (osize > 128)
-                       osize = 128;
-               for (idx = 0; idx < osize; idx++) {
-                       m = vm_page_lookup(object, idx);
-                       if (m == NULL) {
+               pa = -1;
+               TAILQ_FOREACH(m, &object->memq, listq) {
+                       if (m->pindex > 128)
+                               break;
+                       if ((prev_m = TAILQ_PREV(m, pglist, listq)) != NULL &&
+                           prev_m->pindex + 1 != m->pindex) {
                                if (rcount) {
                                        db_printf(" 
index(%ld)run(%d)pa(0x%lx)\n",
                                                (long)fidx, rcount, (long)pa);
@@ -2234,10 +2231,7 @@ DB_SHOW_COMMAND(vmopag, vm_object_print_
                                        nl++;
                                        rcount = 0;
                                }
-                               continue;
-                       }
-
-                               
+                       }                               
                        if (rcount &&
                                (VM_PAGE_TO_PHYS(m) == pa + rcount * 
PAGE_SIZE)) {
                                ++rcount;
@@ -2254,7 +2248,7 @@ DB_SHOW_COMMAND(vmopag, vm_object_print_
                                }
                                nl++;
                        }
-                       fidx = idx;
+                       fidx = m->pindex;
                        pa = VM_PAGE_TO_PHYS(m);
                        rcount = 1;
                }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to