Batch updates to v_wire_count when freeing page table pages on x86.

The removed release stores are not needed since stores are totally
ordered on i386 and amd64.

Reviewed by:	alc, kib (previous revision)
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D11790
This commit is contained in:
Mark Johnston 2017-08-01 05:26:30 +00:00
parent 4271417a84
commit 2375aaa8e9
2 changed files with 8 additions and 24 deletions

View file

@ -2209,12 +2209,14 @@ static __inline void
pmap_free_zero_pages(struct spglist *free)
{
vm_page_t m;
int count;
while ((m = SLIST_FIRST(free)) != NULL) {
for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) {
SLIST_REMOVE_HEAD(free, plinks.s.ss);
/* Preserve the page's PG_ZERO setting. */
vm_page_free_toq(m);
}
atomic_subtract_int(&vm_cnt.v_wire_count, count);
}
/*
@ -2320,13 +2322,6 @@ _pmap_unwire_ptp(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free)
pmap_unwire_ptp(pmap, va, pdppg, free);
}
/*
* This is a release store so that the ordinary store unmapping
* the page table page is globally performed before TLB shoot-
* down is begun.
*/
atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1);
/*
* Put page on a list so that it is released after
* *ALL* TLB shootdown is done
@ -3010,7 +3005,6 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp)
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 +3672,6 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
("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 +5615,6 @@ pmap_remove_pages(pmap_t pmap)
("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);

View file

@ -1709,12 +1709,14 @@ static __inline void
pmap_free_zero_pages(struct spglist *free)
{
vm_page_t m;
int count;
while ((m = SLIST_FIRST(free)) != NULL) {
for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) {
SLIST_REMOVE_HEAD(free, plinks.s.ss);
/* Preserve the page's PG_ZERO setting. */
vm_page_free_toq(m);
}
atomic_subtract_int(&vm_cnt.v_wire_count, count);
}
/*
@ -1791,13 +1793,6 @@ _pmap_unwire_ptp(pmap_t pmap, vm_page_t m, struct spglist *free)
pmap->pm_pdir[m->pindex] = 0;
--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.
*/
atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1);
/*
* Do an invltlb to make the invalidated mapping
* take effect immediately.
@ -2061,11 +2056,11 @@ pmap_release(pmap_t pmap)
("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 +2319,6 @@ out:
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 +2867,6 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
("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 +4586,6 @@ pmap_remove_pages(pmap_t pmap)
("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--;