DragonFly BSD
DragonFly bugs List (threaded) for 2009-12
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: panic: assertion: pmap->pm_stats.resident_count > 0 in pmap_release_free_page


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Dec 2009 20:42:47 -0800 (PST)

: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@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);



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]