panic: assertion: pmap->pm_stats.resident_count > 0 in pmap_release_free_page
Matthew Dillon
dillon at apollo.backplane.com
Wed Dec 23 20:44:06 PST 2009
:Before the syntaxis change was committed, that is, the panic occurs
:on the real kernels built from both versions below:
:
: commit 8e5e6f1b1a2869fdaf18f24243c40e756e6e787a
: commit 376534279570d134799f19f5b0b0bb5c0cd24516
:
:I'll start bisect'ing later.
Ah, ok. I was only git log'ing /usr/src/sys/, 3765 was a commit
in the main source tree :-)
The panic is due to pmap->pm_stats.resident_count being off by 1.
It should have been left with a count of 1 with only the page
directory page left to purge but the count was 0.
I'm thinking possibly something in the pmap unwiring code, possibly
in _pmap_unwire_pte_hold(), could be racing.
Here is a patch to try. It adds a bunch of assertions in an attempt
to catch the potential race.
-Matt
Matthew Dillon
<dillon at backplane.com>
diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c
index 53cc386..b07f2cf 100644
--- a/sys/platform/pc32/i386/pmap.c
+++ b/sys/platform/pc32/i386/pmap.c
@@ -934,6 +934,7 @@ _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info)
*/
vm_page_busy(m);
pmap_inval_add(info, pmap, -1);
+ KKASSERT(pmap->pm_pdir[m->pindex]);
pmap->pm_pdir[m->pindex] = 0;
KKASSERT(pmap->pm_stats.resident_count > 0);
@@ -1153,8 +1154,9 @@ pmap_release_free_page(struct pmap *pmap, vm_page_t p)
/*
* Remove the page table page from the processes address space.
*/
- pde[p->pindex] = 0;
KKASSERT(pmap->pm_stats.resident_count > 0);
+ KKASSERT(pde[p->pindex]);
+ pde[p->pindex] = 0;
--pmap->pm_stats.resident_count;
if (p->hold_count) {
@@ -1604,6 +1606,7 @@ pmap_remove_pte(struct pmap *pmap, unsigned *ptq, vm_offset_t va,
pmap_inval_add(info, pmap, va);
oldpte = loadandclear(ptq);
+ KKASSERT(oldpte);
if (oldpte & PG_W)
pmap->pm_stats.wired_count -= 1;
/*
@@ -2850,6 +2853,7 @@ pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
npv = TAILQ_NEXT(pv, pv_plist);
continue;
}
+ KKASSERT(*pte);
tpte = loadandclear(pte);
m = PHYS_TO_VM_PAGE(tpte);
More information about the Bugs
mailing list