Module Name:    src
Committed By:   thorpej
Date:           Tue Aug 18 19:08:39 UTC 2009

Modified Files:
        src/sys/uvm: uvm_map.c uvm_page.c
Added Files:
        src/sys/uvm: uvm_page_impl.h

Log Message:
Move uvm_page-related DDB hooks into uvm_page.c.


To generate a diff of this commit:
cvs rdiff -u -r1.278 -r1.279 src/sys/uvm/uvm_map.c
cvs rdiff -u -r1.150 -r1.151 src/sys/uvm/uvm_page.c
cvs rdiff -u -r0 -r1.1 src/sys/uvm/uvm_page_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.278 src/sys/uvm/uvm_map.c:1.279
--- src/sys/uvm/uvm_map.c:1.278	Thu Aug 13 03:21:03 2009
+++ src/sys/uvm/uvm_map.c	Tue Aug 18 19:08:39 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.278 2009/08/13 03:21:03 matt Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.279 2009/08/18 19:08:39 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.278 2009/08/13 03:21:03 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.279 2009/08/18 19:08:39 thorpej Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -5097,122 +5097,7 @@
 	}
 }
 
-/*
- * uvm_page_printit: actually print the page
- */
-
-static const char page_flagbits[] = UVM_PGFLAGBITS;
-static const char page_pqflagbits[] = UVM_PQFLAGBITS;
-
-void
-uvm_page_printit(struct vm_page *pg, bool full,
-    void (*pr)(const char *, ...))
-{
-	struct vm_page *tpg;
-	struct uvm_object *uobj;
-	struct pgflist *pgl;
-	char pgbuf[128];
-	char pqbuf[128];
-
-	(*pr)("PAGE %p:\n", pg);
-	snprintb(pgbuf, sizeof(pgbuf), page_flagbits, pg->flags);
-	snprintb(pqbuf, sizeof(pqbuf), page_pqflagbits, pg->pqflags);
-	(*pr)("  flags=%s, pqflags=%s, wire_count=%d, pa=0x%lx\n",
-	    pgbuf, pqbuf, pg->wire_count, (long)VM_PAGE_TO_PHYS(pg));
-	(*pr)("  uobject=%p, uanon=%p, offset=0x%llx loan_count=%d\n",
-	    pg->uobject, pg->uanon, (long long)pg->offset, pg->loan_count);
-#if defined(UVM_PAGE_TRKOWN)
-	if (pg->flags & PG_BUSY)
-		(*pr)("  owning process = %d, tag=%s\n",
-		    pg->owner, pg->owner_tag);
-	else
-		(*pr)("  page not busy, no owner\n");
-#else
-	(*pr)("  [page ownership tracking disabled]\n");
-#endif
-
-	if (!full)
-		return;
-
-	/* cross-verify object/anon */
-	if ((pg->pqflags & PQ_FREE) == 0) {
-		if (pg->pqflags & PQ_ANON) {
-			if (pg->uanon == NULL || pg->uanon->an_page != pg)
-			    (*pr)("  >>> ANON DOES NOT POINT HERE <<< (%p)\n",
-				(pg->uanon) ? pg->uanon->an_page : NULL);
-			else
-				(*pr)("  anon backpointer is OK\n");
-		} else {
-			uobj = pg->uobject;
-			if (uobj) {
-				(*pr)("  checking object list\n");
-				TAILQ_FOREACH(tpg, &uobj->memq, listq.queue) {
-					if (tpg == pg) {
-						break;
-					}
-				}
-				if (tpg)
-					(*pr)("  page found on object list\n");
-				else
-			(*pr)("  >>> PAGE NOT FOUND ON OBJECT LIST! <<<\n");
-			}
-		}
-	}
-
-	/* cross-verify page queue */
-	if (pg->pqflags & PQ_FREE) {
-		int fl = uvm_page_lookup_freelist(pg);
-		int color = VM_PGCOLOR_BUCKET(pg);
-		pgl = &uvm.page_free[fl].pgfl_buckets[color].pgfl_queues[
-		    ((pg)->flags & PG_ZERO) ? PGFL_ZEROS : PGFL_UNKNOWN];
-	} else {
-		pgl = NULL;
-	}
-
-	if (pgl) {
-		(*pr)("  checking pageq list\n");
-		LIST_FOREACH(tpg, pgl, pageq.list) {
-			if (tpg == pg) {
-				break;
-			}
-		}
-		if (tpg)
-			(*pr)("  page found on pageq list\n");
-		else
-			(*pr)("  >>> PAGE NOT FOUND ON PAGEQ LIST! <<<\n");
-	}
-}
-
-/*
- * uvm_pages_printthem - print a summary of all managed pages
- */
-
-void
-uvm_page_printall(void (*pr)(const char *, ...))
-{
-	unsigned i;
-	struct vm_page *pg;
-
-	(*pr)("%18s %4s %4s %18s %18s"
-#ifdef UVM_PAGE_TRKOWN
-	    " OWNER"
-#endif
-	    "\n", "PAGE", "FLAG", "PQ", "UOBJECT", "UANON");
-	for (i = 0; i < vm_nphysseg; i++) {
-		for (pg = vm_physmem[i].pgs; pg <= vm_physmem[i].lastpg; pg++) {
-			(*pr)("%18p %04x %04x %18p %18p",
-			    pg, pg->flags, pg->pqflags, pg->uobject,
-			    pg->uanon);
-#ifdef UVM_PAGE_TRKOWN
-			if (pg->flags & PG_BUSY)
-				(*pr)(" %d [%s]", pg->owner, pg->owner_tag);
-#endif
-			(*pr)("\n");
-		}
-	}
-}
-
-#endif
+#endif /* DDB || DEBUGPRINT */
 
 /*
  * uvm_map_create: create map

Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.150 src/sys/uvm/uvm_page.c:1.151
--- src/sys/uvm/uvm_page.c:1.150	Tue Aug 18 18:06:53 2009
+++ src/sys/uvm/uvm_page.c	Tue Aug 18 19:08:39 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_page.c,v 1.150 2009/08/18 18:06:53 thorpej Exp $	*/
+/*	$NetBSD: uvm_page.c,v 1.151 2009/08/18 19:08:39 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,8 +71,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.150 2009/08/18 18:06:53 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.151 2009/08/18 19:08:39 thorpej Exp $");
 
+#include "opt_ddb.h"
 #include "opt_uvmhist.h"
 #include "opt_readahead.h"
 
@@ -87,6 +88,7 @@
 #include <sys/cpu.h>
 
 #include <uvm/uvm.h>
+#include <uvm/uvm_ddb.h>
 #include <uvm/uvm_pdpolicy.h>
 
 /*
@@ -1873,3 +1875,122 @@
 	KASSERT(lcv != -1);
 	return (vm_physmem[lcv].free_list);
 }
+
+#if defined(DDB) || defined(DEBUGPRINT)
+
+/*
+ * uvm_page_printit: actually print the page
+ */
+
+static const char page_flagbits[] = UVM_PGFLAGBITS;
+static const char page_pqflagbits[] = UVM_PQFLAGBITS;
+
+void
+uvm_page_printit(struct vm_page *pg, bool full,
+    void (*pr)(const char *, ...))
+{
+	struct vm_page *tpg;
+	struct uvm_object *uobj;
+	struct pgflist *pgl;
+	char pgbuf[128];
+	char pqbuf[128];
+
+	(*pr)("PAGE %p:\n", pg);
+	snprintb(pgbuf, sizeof(pgbuf), page_flagbits, pg->flags);
+	snprintb(pqbuf, sizeof(pqbuf), page_pqflagbits, pg->pqflags);
+	(*pr)("  flags=%s, pqflags=%s, wire_count=%d, pa=0x%lx\n",
+	    pgbuf, pqbuf, pg->wire_count, (long)VM_PAGE_TO_PHYS(pg));
+	(*pr)("  uobject=%p, uanon=%p, offset=0x%llx loan_count=%d\n",
+	    pg->uobject, pg->uanon, (long long)pg->offset, pg->loan_count);
+#if defined(UVM_PAGE_TRKOWN)
+	if (pg->flags & PG_BUSY)
+		(*pr)("  owning process = %d, tag=%s\n",
+		    pg->owner, pg->owner_tag);
+	else
+		(*pr)("  page not busy, no owner\n");
+#else
+	(*pr)("  [page ownership tracking disabled]\n");
+#endif
+
+	if (!full)
+		return;
+
+	/* cross-verify object/anon */
+	if ((pg->pqflags & PQ_FREE) == 0) {
+		if (pg->pqflags & PQ_ANON) {
+			if (pg->uanon == NULL || pg->uanon->an_page != pg)
+			    (*pr)("  >>> ANON DOES NOT POINT HERE <<< (%p)\n",
+				(pg->uanon) ? pg->uanon->an_page : NULL);
+			else
+				(*pr)("  anon backpointer is OK\n");
+		} else {
+			uobj = pg->uobject;
+			if (uobj) {
+				(*pr)("  checking object list\n");
+				TAILQ_FOREACH(tpg, &uobj->memq, listq.queue) {
+					if (tpg == pg) {
+						break;
+					}
+				}
+				if (tpg)
+					(*pr)("  page found on object list\n");
+				else
+			(*pr)("  >>> PAGE NOT FOUND ON OBJECT LIST! <<<\n");
+			}
+		}
+	}
+
+	/* cross-verify page queue */
+	if (pg->pqflags & PQ_FREE) {
+		int fl = uvm_page_lookup_freelist(pg);
+		int color = VM_PGCOLOR_BUCKET(pg);
+		pgl = &uvm.page_free[fl].pgfl_buckets[color].pgfl_queues[
+		    ((pg)->flags & PG_ZERO) ? PGFL_ZEROS : PGFL_UNKNOWN];
+	} else {
+		pgl = NULL;
+	}
+
+	if (pgl) {
+		(*pr)("  checking pageq list\n");
+		LIST_FOREACH(tpg, pgl, pageq.list) {
+			if (tpg == pg) {
+				break;
+			}
+		}
+		if (tpg)
+			(*pr)("  page found on pageq list\n");
+		else
+			(*pr)("  >>> PAGE NOT FOUND ON PAGEQ LIST! <<<\n");
+	}
+}
+
+/*
+ * uvm_pages_printthem - print a summary of all managed pages
+ */
+
+void
+uvm_page_printall(void (*pr)(const char *, ...))
+{
+	unsigned i;
+	struct vm_page *pg;
+
+	(*pr)("%18s %4s %4s %18s %18s"
+#ifdef UVM_PAGE_TRKOWN
+	    " OWNER"
+#endif
+	    "\n", "PAGE", "FLAG", "PQ", "UOBJECT", "UANON");
+	for (i = 0; i < vm_nphysseg; i++) {
+		for (pg = vm_physmem[i].pgs; pg <= vm_physmem[i].lastpg; pg++) {
+			(*pr)("%18p %04x %04x %18p %18p",
+			    pg, pg->flags, pg->pqflags, pg->uobject,
+			    pg->uanon);
+#ifdef UVM_PAGE_TRKOWN
+			if (pg->flags & PG_BUSY)
+				(*pr)(" %d [%s]", pg->owner, pg->owner_tag);
+#endif
+			(*pr)("\n");
+		}
+	}
+}
+
+#endif /* DDB || DEBUGPRINT */

Added files:

Index: src/sys/uvm/uvm_page_impl.h
diff -u /dev/null src/sys/uvm/uvm_page_impl.h:1.1
--- /dev/null	Tue Aug 18 19:08:39 2009
+++ src/sys/uvm/uvm_page_impl.h	Tue Aug 18 19:08:39 2009
@@ -0,0 +1,202 @@
+/*	$NetBSD: uvm_page_impl.h,v 1.1 2009/08/18 19:08:39 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 1997 Charles D. Cranor and Washington University.
+ * Copyright (c) 1991, 1993, The Regents of the University of California.
+ *
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Charles D. Cranor,
+ *      Washington University, the University of California, Berkeley and
+ *      its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)vm_page.h   7.3 (Berkeley) 4/21/91
+ * from: Id: uvm_page.h,v 1.1.2.6 1998/02/04 02:31:42 chuck Exp
+ *
+ *
+ * Copyright (c) 1987, 1990 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  software.distribut...@cs.cmu.edu
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _UVM_UVM_PAGE_IMPL_H_
+#define _UVM_UVM_PAGE_IMPL_H_
+
+/*
+ * uvm_page_impl.h
+ */
+
+/*
+ *	Private resident memory system definitions.
+ */
+
+#include <uvm/uvm_page.h>
+
+/*
+ * physical memory layout structure
+ *
+ * MD vmparam.h must #define:
+ *   VM_PHYSEG_MAX = max number of physical memory segments we support
+ *		   (if this is "1" then we revert to a "contig" case)
+ *   VM_PHYSSEG_STRAT: memory sort/search options (for VM_PHYSEG_MAX > 1)
+ * 	- VM_PSTRAT_RANDOM:   linear search (random order)
+ *	- VM_PSTRAT_BSEARCH:  binary search (sorted by address)
+ *	- VM_PSTRAT_BIGFIRST: linear search (sorted by largest segment first)
+ *      - others?
+ *   XXXCDC: eventually we should purge all left-over global variables...
+ */
+#define VM_PSTRAT_RANDOM	1
+#define VM_PSTRAT_BSEARCH	2
+#define VM_PSTRAT_BIGFIRST	3
+
+/*
+ * vm_physseg: describes one segment of physical memory
+ */
+struct vm_physseg {
+	paddr_t	start;			/* PF# of first page in segment */
+	paddr_t	end;			/* (PF# of last page in segment) + 1 */
+	paddr_t	avail_start;		/* PF# of first free page in segment */
+	paddr_t	avail_end;		/* (PF# of last free page in segment) +1  */
+	int	free_list;		/* which free list they belong on */
+	struct	vm_page *pgs;		/* vm_page structures (from start) */
+	struct	vm_page *lastpg;	/* vm_page structure for end */
+#ifdef __HAVE_PMAP_PHYSSEG
+	struct	pmap_physseg pmseg;	/* pmap specific (MD) data */
+#endif
+};
+
+#ifdef _KERNEL
+
+/*
+ * physical memory config is stored in vm_physmem.
+ */
+
+extern struct vm_physseg vm_physmem[VM_PHYSSEG_MAX];
+extern int vm_nphysseg;
+
+/*
+ * when VM_PHYSSEG_MAX is 1, we can simplify these functions
+ */
+
+/*
+ * vm_physseg_find: find vm_physseg structure that belongs to a PA
+ */
+static __inline int
+vm_physseg_find(paddr_t pframe, int *offp)
+{
+#if VM_PHYSSEG_MAX == 1
+
+	/* 'contig' case */
+	if (pframe >= vm_physmem[0].start && pframe < vm_physmem[0].end) {
+		if (offp)
+			*offp = pframe - vm_physmem[0].start;
+		return(0);
+	}
+	return(-1);
+
+#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
+	/* binary search for it */
+	u_int	start, len, try;
+
+	/*
+	 * if try is too large (thus target is less than try) we reduce
+	 * the length to trunc(len/2) [i.e. everything smaller than "try"]
+	 *
+	 * if the try is too small (thus target is greater than try) then
+	 * we set the new start to be (try + 1).   this means we need to
+	 * reduce the length to (round(len/2) - 1).
+	 *
+	 * note "adjust" below which takes advantage of the fact that
+	 *  (round(len/2) - 1) == trunc((len - 1) / 2)
+	 * for any value of len we may have
+	 */
+
+	for (start = 0, len = vm_nphysseg ; len != 0 ; len = len / 2) {
+		try = start + (len / 2);	/* try in the middle */
+
+		/* start past our try? */
+		if (pframe >= vm_physmem[try].start) {
+			/* was try correct? */
+			if (pframe < vm_physmem[try].end) {
+				if (offp)
+					*offp = pframe - vm_physmem[try].start;
+				return(try);            /* got it */
+			}
+			start = try + 1;	/* next time, start here */
+			len--;			/* "adjust" */
+		} else {
+			/*
+			 * pframe before try, just reduce length of
+			 * region, done in "for" loop
+			 */
+		}
+	}
+	return(-1);
+
+#else
+	/* linear search for it */
+	int	lcv;
+
+	for (lcv = 0; lcv < vm_nphysseg; lcv++) {
+		if (pframe >= vm_physmem[lcv].start &&
+		    pframe < vm_physmem[lcv].end) {
+			if (offp)
+				*offp = pframe - vm_physmem[lcv].start;
+			return(lcv);		   /* got it */
+		}
+	}
+	return(-1);
+
+#endif
+}
+
+#endif /* _KERNEL */
+
+#endif /* _UVM_UVM_PAGE_IMPL_H_ */

Reply via email to