Module Name: src Committed By: chs Date: Tue Nov 13 14:09:36 UTC 2012
Modified Files: src/sys/arch/amd64/amd64: machdep.c Log Message: fix sparse crash dumps to contain enough data to be useful, in particular the top-level page table pages. use pmap_kremove_local() while writing crash dumps to avoid spurious warning messages. To generate a diff of this commit: cvs rdiff -u -r1.190 -r1.191 src/sys/arch/amd64/amd64/machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.190 src/sys/arch/amd64/amd64/machdep.c:1.191 --- src/sys/arch/amd64/amd64/machdep.c:1.190 Mon Sep 3 05:01:44 2012 +++ src/sys/arch/amd64/amd64/machdep.c Tue Nov 13 14:09:36 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.190 2012/09/03 05:01:44 cherry Exp $ */ +/* $NetBSD: machdep.c,v 1.191 2012/11/13 14:09:36 chs Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.190 2012/09/03 05:01:44 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.191 2012/11/13 14:09:36 chs Exp $"); /* #define XENDEBUG_LOW */ @@ -317,7 +317,7 @@ int dump_seg_iter(int (*)(paddr_t, paddr #ifndef NO_SPARSE_DUMP void sparse_dump_reset(void); -void sparse_dump_mark(vaddr_t, vaddr_t, int); +void sparse_dump_mark(void); void cpu_dump_prep_sparse(void); #endif @@ -821,7 +821,7 @@ haltsys: * XXXfvdl share dumpcode. */ - /* +/* * Perform assorted dump-related initialization tasks. Assumes that * the maximum physical memory address will not increase afterwards. */ @@ -873,34 +873,39 @@ sparse_dump_reset(void) } /* - * Include or exclude pages in a sparse dump, by half-open virtual - * address interval (which may wrap around the end of the space). + * Include or exclude pages in a sparse dump. */ void -sparse_dump_mark(vaddr_t vbegin, vaddr_t vend, int includep) +sparse_dump_mark(void) { - pmap_t pmap; - paddr_t p; - vaddr_t v; + paddr_t p, pstart, pend; + struct vm_page *pg; + int i; /* - * If a partial page is called for, the whole page must be included. + * Mark all memory pages, then unmark pages that are uninteresting. + * Dereferenceing pg->uobject might crash again if another CPU + * frees the object out from under us, but we can't lock anything + * so it's a risk we have to take. */ - if (includep) { - vbegin = rounddown(vbegin, PAGE_SIZE); - vend = roundup(vend, PAGE_SIZE); - } else { - vbegin = roundup(vbegin, PAGE_SIZE); - vend = rounddown(vend, PAGE_SIZE); + + for (i = 0; i < mem_cluster_cnt; ++i) { + pstart = mem_clusters[i].start / PAGE_SIZE; + pend = pstart + mem_clusters[i].size / PAGE_SIZE; + + for (p = pstart; p < pend; p++) { + setbit(sparse_dump_physmap, p); + } } + for (i = 0; i < vm_nphysseg; i++) { + struct vm_physseg *seg = VM_PHYSMEM_PTR(i); - pmap = pmap_kernel(); - for (v = vbegin; v != vend; v += PAGE_SIZE) { - if (pmap_extract(pmap, v, &p)) { - if (includep) - setbit(sparse_dump_physmap, p/PAGE_SIZE); - else - clrbit(sparse_dump_physmap, p/PAGE_SIZE); + for (pg = seg->pgs; pg < seg->lastpg; pg++) { + if (pg->uanon || (pg->pqflags & PQ_FREE) || + (pg->uobject && pg->uobject->pgops)) { + p = VM_PAGE_TO_PHYS(pg) / PAGE_SIZE; + clrbit(sparse_dump_physmap, p); + } } } } @@ -914,7 +919,7 @@ cpu_dump_prep_sparse(void) { sparse_dump_reset(); /* XXX could the alternate recursive page table be skipped? */ - sparse_dump_mark((vaddr_t)PTE_BASE, (vaddr_t)KERN_BASE, 1); + sparse_dump_mark(); /* Memory for I/O buffers could be unmarked here, for example. */ /* The kernel text could also be unmarked, but gdb would be upset. */ } @@ -1206,6 +1211,7 @@ dumpsys_seg(paddr_t maddr, paddr_t bytes pmap_update(pmap_kernel()); error = (*dump)(dumpdev, blkno, (void *)dumpspace, n); + pmap_kremove_local(dumpspace, n); if (error) return error; maddr += n;