: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 
                                        <[email protected]>

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

Reply via email to