Index: sys/amd64/amd64/pmap.c =================================================================== --- sys/amd64/amd64/pmap.c +++ sys/amd64/amd64/pmap.c @@ -2209,12 +2209,16 @@ pmap_free_zero_pages(struct spglist *free) { vm_page_t m; + int count; + count = 0; while ((m = SLIST_FIRST(free)) != NULL) { SLIST_REMOVE_HEAD(free, plinks.s.ss); /* Preserve the page's PG_ZERO setting. */ vm_page_free_toq(m); + count++; } + atomic_subtract_int(&vm_cnt.v_wire_count, count); } /* @@ -2321,11 +2325,10 @@ } /* - * This is a release store so that the ordinary store unmapping - * the page table page is globally performed before TLB shoot- - * down is begun. + * Ensure that the ordinary store unmapping the page table page is + * globally visible before TLB shootdown is begun. */ - atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1); + atomic_thread_fence_rel(); /* * Put page on a list so that it is released after @@ -3010,7 +3013,6 @@ SLIST_REMOVE_HEAD(&free, plinks.s.ss); /* Recycle a freed page table page. */ m_pc->wire_count = 1; - atomic_add_int(&vm_cnt.v_wire_count, 1); } pmap_free_zero_pages(&free); return (m_pc); @@ -3678,7 +3680,6 @@ ("pmap_remove_pde: pte page wire count error")); mpte->wire_count = 0; pmap_add_delayed_free_list(mpte, free, FALSE); - atomic_subtract_int(&vm_cnt.v_wire_count, 1); } } return (pmap_unuse_pt(pmap, sva, *pmap_pdpe(pmap, sva), free)); @@ -5622,7 +5623,6 @@ ("pmap_remove_pages: pte page wire count error")); mpte->wire_count = 0; pmap_add_delayed_free_list(mpte, &free, FALSE); - atomic_subtract_int(&vm_cnt.v_wire_count, 1); } } else { pmap_resident_count_dec(pmap, 1); Index: sys/i386/i386/pmap.c =================================================================== --- sys/i386/i386/pmap.c +++ sys/i386/i386/pmap.c @@ -1792,11 +1792,10 @@ --pmap->pm_stats.resident_count; /* - * This is a release store so that the ordinary store unmapping - * the page table page is globally performed before TLB shoot- - * down is begun. + * Ensure that the ordinary store unmapping the page table page is + * globally visible before TLB shootdown is begun. */ - atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1); + atomic_thread_fence_rel(); /* * Do an invltlb to make the invalidated mapping @@ -2061,11 +2060,11 @@ ("pmap_release: got wrong ptd page")); #endif m->wire_count--; - atomic_subtract_int(&vm_cnt.v_wire_count, 1); vm_page_free_zero(m); } + atomic_subtract_int(&vm_cnt.v_wire_count, NPGPTD); } - + static int kvm_size(SYSCTL_HANDLER_ARGS) { @@ -2324,7 +2323,6 @@ SLIST_REMOVE_HEAD(&free, plinks.s.ss); /* Recycle a freed page table page. */ m_pc->wire_count = 1; - atomic_add_int(&vm_cnt.v_wire_count, 1); } pmap_free_zero_pages(&free); return (m_pc); @@ -2873,7 +2871,6 @@ ("pmap_remove_pde: pte page wire count error")); mpte->wire_count = 0; pmap_add_delayed_free_list(mpte, free, FALSE); - atomic_subtract_int(&vm_cnt.v_wire_count, 1); } } } @@ -4593,7 +4590,6 @@ ("pmap_remove_pages: pte page wire count error")); mpte->wire_count = 0; pmap_add_delayed_free_list(mpte, &free, FALSE); - atomic_subtract_int(&vm_cnt.v_wire_count, 1); } } else { pmap->pm_stats.resident_count--;