Push down page queues lock acquisition in pmap_enter_object() and
pmap_is_referenced(). Eliminate the corresponding page queues lock acquisitions from vm_map_pmap_enter() and mincore(), respectively. In mincore(), this allows some additional cases to complete without ever acquiring the page queues lock. Assert that the page is managed in pmap_is_referenced(). On powerpc/aim, push down the page queues lock acquisition from moea*_is_modified() and moea*_is_referenced() into moea*_query_bit(). Again, this will allow some additional cases to complete without ever acquiring the page queues lock. Reorder a few statements in vm_page_dontneed() so that a race can't lead to an old reference persisting. This scenario is described in detail by a comment. Correct a spelling error in vm_page_dontneed(). Assert that the object is locked in vm_page_clear_dirty(), and restrict the page queues lock assertion to just those cases in which the page is currently writeable. Add object locking to vnode_pager_generic_putpages(). This was the one and only place where vm_page_clear_dirty() was being called without the object being locked. Eliminate an unnecessary vm_page_lock() around vnode_pager_setsize()'s call to vm_page_clear_dirty(). Change vnode_pager_generic_putpages() to the modern-style of function definition. Also, change the name of one of the parameters to follow virtual memory system naming conventions. Reviewed by: kib
This commit is contained in:
parent
55e1b13327
commit
c46b90e90a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=208574
@ -3389,6 +3389,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
psize = atop(end - start);
|
||||
mpte = NULL;
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
va = start + ptoa(diff);
|
||||
@ -3402,6 +3403,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
mpte);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -4209,12 +4211,15 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
|
||||
boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
boolean_t rv;
|
||||
|
||||
if (m->flags & PG_FICTITIOUS)
|
||||
return (FALSE);
|
||||
if (pmap_is_referenced_pvh(&m->md))
|
||||
return (TRUE);
|
||||
return (pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
vm_page_lock_queues();
|
||||
rv = pmap_is_referenced_pvh(&m->md) ||
|
||||
pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)));
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3589,12 +3589,14 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
pmap_enter_locked(pmap, start + ptoa(diff), m, prot &
|
||||
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE, M_NOWAIT);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -4521,8 +4523,9 @@ boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
|
||||
return ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0 &&
|
||||
(m->md.pvh_attrs & PVF_REF) != 0);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
return ((m->md.pvh_attrs & PVF_REF) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3519,6 +3519,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
psize = atop(end - start);
|
||||
mpte = NULL;
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
va = start + ptoa(diff);
|
||||
@ -3532,6 +3533,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
mpte);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -4377,12 +4379,15 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
|
||||
boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
boolean_t rv;
|
||||
|
||||
if (m->flags & PG_FICTITIOUS)
|
||||
return (FALSE);
|
||||
if (pmap_is_referenced_pvh(&m->md))
|
||||
return (TRUE);
|
||||
return (pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
vm_page_lock_queues();
|
||||
rv = pmap_is_referenced_pvh(&m->md) ||
|
||||
pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)));
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2901,6 +2901,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
mpte = NULL;
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
mpte = pmap_enter_quick_locked(&mclp, &count, pmap, start + ptoa(diff), m,
|
||||
@ -2917,7 +2918,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
error = HYPERVISOR_multicall(mcl, count);
|
||||
KASSERT(error == 0, ("bad multicall %d", error));
|
||||
}
|
||||
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -3734,11 +3735,11 @@ pmap_is_referenced(vm_page_t m)
|
||||
pmap_t pmap;
|
||||
boolean_t rv;
|
||||
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
rv = FALSE;
|
||||
if (m->flags & PG_FICTITIOUS)
|
||||
return (rv);
|
||||
vm_page_lock_queues();
|
||||
sched_pin();
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
|
||||
pmap = PV_PMAP(pv);
|
||||
PMAP_LOCK(pmap);
|
||||
@ -3751,6 +3752,7 @@ pmap_is_referenced(vm_page_t m)
|
||||
if (*PMAP1)
|
||||
PT_SET_MA(PADDR1, 0);
|
||||
sched_unpin();
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -1625,12 +1625,14 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED);
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
oldpmap = pmap_switch(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
pmap_enter_quick_locked(pmap, start + ptoa(diff), m, prot);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
pmap_switch(oldpmap);
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
@ -2041,9 +2043,10 @@ pmap_is_referenced(vm_page_t m)
|
||||
pv_entry_t pv;
|
||||
boolean_t rv;
|
||||
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
rv = FALSE;
|
||||
if (m->flags & PG_FICTITIOUS)
|
||||
return (rv);
|
||||
vm_page_lock_queues();
|
||||
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
|
||||
PMAP_LOCK(pv->pv_pmap);
|
||||
oldpmap = pmap_switch(pv->pv_pmap);
|
||||
@ -2055,6 +2058,7 @@ pmap_is_referenced(vm_page_t m)
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -2130,12 +2130,14 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
psize = atop(end - start);
|
||||
mpte = NULL;
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
mpte = pmap_enter_quick_locked(pmap, start + ptoa(diff), m,
|
||||
prot, mpte);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -2671,8 +2673,9 @@ boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
|
||||
return ((m->flags & PG_FICTITIOUS) == 0 &&
|
||||
(m->md.pv_flags & PV_TABLE_REF) != 0);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
return ((m->md.pv_flags & PV_TABLE_REF) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1197,12 +1197,14 @@ moea_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pm);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
moea_enter_locked(pm, start + ptoa(diff), m, prot &
|
||||
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pm);
|
||||
}
|
||||
|
||||
@ -1282,15 +1284,14 @@ boolean_t
|
||||
moea_is_referenced(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
|
||||
if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
|
||||
return (FALSE);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("moea_is_referenced: page %p is not managed", m));
|
||||
return (moea_query_bit(m, PTE_REF));
|
||||
}
|
||||
|
||||
boolean_t
|
||||
moea_is_modified(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
boolean_t rv;
|
||||
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("moea_is_modified: page %p is not managed", m));
|
||||
@ -1304,10 +1305,7 @@ moea_is_modified(mmu_t mmu, vm_page_t m)
|
||||
if ((m->oflags & VPO_BUSY) == 0 &&
|
||||
(m->flags & PG_WRITEABLE) == 0)
|
||||
return (FALSE);
|
||||
vm_page_lock_queues();
|
||||
rv = moea_query_bit(m, PTE_CHG);
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
return (moea_query_bit(m, PTE_CHG));
|
||||
}
|
||||
|
||||
void
|
||||
@ -2268,6 +2266,7 @@ moea_query_bit(vm_page_t m, int ptebit)
|
||||
if (moea_attr_fetch(m) & ptebit)
|
||||
return (TRUE);
|
||||
|
||||
vm_page_lock_queues();
|
||||
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
|
||||
@ -2278,6 +2277,7 @@ moea_query_bit(vm_page_t m, int ptebit)
|
||||
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
|
||||
moea_attr_save(m, ptebit);
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
vm_page_unlock_queues();
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
@ -2303,11 +2303,13 @@ moea_query_bit(vm_page_t m, int ptebit)
|
||||
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
|
||||
moea_attr_save(m, ptebit);
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
vm_page_unlock_queues();
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm_page_unlock_queues();
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
@ -1330,12 +1330,14 @@ moea64_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pm);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
moea64_enter_locked(pm, start + ptoa(diff), m, prot &
|
||||
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pm);
|
||||
}
|
||||
|
||||
@ -1477,15 +1479,14 @@ boolean_t
|
||||
moea64_is_referenced(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
|
||||
if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
|
||||
return (FALSE);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("moea64_is_referenced: page %p is not managed", m));
|
||||
return (moea64_query_bit(m, PTE_REF));
|
||||
}
|
||||
|
||||
boolean_t
|
||||
moea64_is_modified(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
boolean_t rv;
|
||||
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("moea64_is_modified: page %p is not managed", m));
|
||||
@ -1499,10 +1500,7 @@ moea64_is_modified(mmu_t mmu, vm_page_t m)
|
||||
if ((m->oflags & VPO_BUSY) == 0 &&
|
||||
(m->flags & PG_WRITEABLE) == 0)
|
||||
return (FALSE);
|
||||
vm_page_lock_queues();
|
||||
rv = moea64_query_bit(m, LPTE_CHG);
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
return (moea64_query_bit(m, LPTE_CHG));
|
||||
}
|
||||
|
||||
void
|
||||
@ -2394,7 +2392,7 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
|
||||
if (moea64_attr_fetch(m) & ptebit)
|
||||
return (TRUE);
|
||||
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
vm_page_lock_queues();
|
||||
|
||||
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
@ -2406,6 +2404,7 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
|
||||
if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
|
||||
moea64_attr_save(m, ptebit);
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
vm_page_unlock_queues();
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
@ -2433,12 +2432,14 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
|
||||
|
||||
moea64_attr_save(m, ptebit);
|
||||
MOEA_PVO_CHECK(pvo); /* sanity check */
|
||||
vm_page_unlock_queues();
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
UNLOCK_TABLE();
|
||||
}
|
||||
|
||||
vm_page_unlock_queues();
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
@ -1711,12 +1711,14 @@ mmu_booke_enter_object(mmu_t mmu, pmap_t pmap, vm_offset_t start,
|
||||
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
mmu_booke_enter_locked(mmu, pmap, start + ptoa(diff), m,
|
||||
prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -2209,19 +2211,22 @@ mmu_booke_is_referenced(mmu_t mmu, vm_page_t m)
|
||||
pv_entry_t pv;
|
||||
boolean_t rv;
|
||||
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("mmu_booke_is_referenced: page %p is not managed", m));
|
||||
rv = FALSE;
|
||||
if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
|
||||
return (rv);
|
||||
vm_page_lock_queues();
|
||||
TAILQ_FOREACH(pv, &m->md.pv_list, pv_link) {
|
||||
PMAP_LOCK(pv->pv_pmap);
|
||||
if ((pte = pte_find(mmu, pv->pv_pmap, pv->pv_va)) != NULL &&
|
||||
PTE_ISVALID(pte))
|
||||
rv = PTE_ISREFERENCED(pte) ? TRUE : FALSE;
|
||||
PTE_ISVALID(pte)) {
|
||||
if (PTE_ISREFERENCED(pte))
|
||||
rv = TRUE;
|
||||
}
|
||||
PMAP_UNLOCK(pv->pv_pmap);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -1492,12 +1492,14 @@ pmap_enter_object(pmap_t pm, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pm);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
pmap_enter_locked(pm, start + ptoa(diff), m, prot &
|
||||
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pm);
|
||||
}
|
||||
|
||||
@ -1947,17 +1949,22 @@ boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
struct tte *tp;
|
||||
boolean_t rv;
|
||||
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
|
||||
return (FALSE);
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
rv = FALSE;
|
||||
vm_page_lock_queues();
|
||||
TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
|
||||
if ((tp->tte_data & TD_PV) == 0)
|
||||
continue;
|
||||
if ((tp->tte_data & TD_REF) != 0)
|
||||
return (TRUE);
|
||||
if ((tp->tte_data & TD_REF) != 0) {
|
||||
rv = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1221,11 +1221,13 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
||||
VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED);
|
||||
psize = atop(end - start);
|
||||
m = m_start;
|
||||
vm_page_lock_queues();
|
||||
PMAP_LOCK(pmap);
|
||||
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
|
||||
pmap_enter_quick_locked(pmap, start + ptoa(diff), m, prot);
|
||||
m = TAILQ_NEXT(m, listq);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
|
||||
@ -1642,8 +1644,14 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
|
||||
boolean_t
|
||||
pmap_is_referenced(vm_page_t m)
|
||||
{
|
||||
boolean_t rv;
|
||||
|
||||
return (tte_get_phys_bit(m, VTD_REF));
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
|
||||
("pmap_is_referenced: page %p is not managed", m));
|
||||
vm_page_lock_queues();
|
||||
rv = tte_get_phys_bit(m, VTD_REF);
|
||||
vm_page_unlock_queues();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1726,7 +1726,6 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
|
||||
vm_offset_t start;
|
||||
vm_page_t p, p_start;
|
||||
vm_pindex_t psize, tmpidx;
|
||||
boolean_t are_queues_locked;
|
||||
|
||||
if ((prot & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0 || object == NULL)
|
||||
return;
|
||||
@ -1748,7 +1747,6 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
|
||||
psize = object->size - pindex;
|
||||
}
|
||||
|
||||
are_queues_locked = FALSE;
|
||||
start = 0;
|
||||
p_start = NULL;
|
||||
|
||||
@ -1782,25 +1780,14 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
|
||||
p_start = p;
|
||||
}
|
||||
} else if (p_start != NULL) {
|
||||
if (!are_queues_locked) {
|
||||
are_queues_locked = TRUE;
|
||||
vm_page_lock_queues();
|
||||
}
|
||||
pmap_enter_object(map->pmap, start, addr +
|
||||
ptoa(tmpidx), p_start, prot);
|
||||
p_start = NULL;
|
||||
}
|
||||
}
|
||||
if (p_start != NULL) {
|
||||
if (!are_queues_locked) {
|
||||
are_queues_locked = TRUE;
|
||||
vm_page_lock_queues();
|
||||
}
|
||||
if (p_start != NULL)
|
||||
pmap_enter_object(map->pmap, start, addr + ptoa(psize),
|
||||
p_start, prot);
|
||||
}
|
||||
if (are_queues_locked)
|
||||
vm_page_unlock_queues();
|
||||
unlock_return:
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
}
|
||||
|
@ -912,11 +912,18 @@ mincore(td, uap)
|
||||
vm_page_dirty(m);
|
||||
if (m->dirty != 0)
|
||||
mincoreinfo |= MINCORE_MODIFIED_OTHER;
|
||||
vm_page_lock_queues();
|
||||
/*
|
||||
* The first test for PG_REFERENCED is an
|
||||
* optimization. The second test is
|
||||
* required because a concurrent pmap
|
||||
* operation could clear the last reference
|
||||
* and set PG_REFERENCED before the call to
|
||||
* pmap_is_referenced().
|
||||
*/
|
||||
if ((m->flags & PG_REFERENCED) != 0 ||
|
||||
pmap_is_referenced(m))
|
||||
pmap_is_referenced(m) ||
|
||||
(m->flags & PG_REFERENCED) != 0)
|
||||
mincoreinfo |= MINCORE_REFERENCED_OTHER;
|
||||
vm_page_unlock_queues();
|
||||
}
|
||||
if (object != NULL)
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
|
@ -1894,7 +1894,7 @@ vm_page_dontneed(vm_page_t m)
|
||||
PCPU_INC(dnweight);
|
||||
|
||||
/*
|
||||
* occassionally leave the page alone
|
||||
* Occasionally leave the page alone.
|
||||
*/
|
||||
if ((dnw & 0x01F0) == 0 ||
|
||||
VM_PAGE_INQUEUE2(m, PQ_INACTIVE)) {
|
||||
@ -1906,11 +1906,18 @@ vm_page_dontneed(vm_page_t m)
|
||||
/*
|
||||
* Clear any references to the page. Otherwise, the page daemon will
|
||||
* immediately reactivate the page.
|
||||
*
|
||||
* Perform the pmap_clear_reference() first. Otherwise, a concurrent
|
||||
* pmap operation, such as pmap_remove(), could clear a reference in
|
||||
* the pmap and set PG_REFERENCED on the page before the
|
||||
* pmap_clear_reference() had completed. Consequently, the page would
|
||||
* appear referenced based upon an old reference that occurred before
|
||||
* this function ran.
|
||||
*/
|
||||
pmap_clear_reference(m);
|
||||
vm_page_lock_queues();
|
||||
vm_page_flag_clear(m, PG_REFERENCED);
|
||||
vm_page_unlock_queues();
|
||||
pmap_clear_reference(m);
|
||||
|
||||
if (m->dirty == 0 && pmap_is_modified(m))
|
||||
vm_page_dirty(m);
|
||||
@ -2142,7 +2149,9 @@ void
|
||||
vm_page_clear_dirty(vm_page_t m, int base, int size)
|
||||
{
|
||||
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
|
||||
if ((m->flags & PG_WRITEABLE) != 0)
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
m->dirty &= ~vm_page_bits(base, size);
|
||||
}
|
||||
|
||||
|
@ -429,11 +429,9 @@ vnode_pager_setsize(vp, nsize)
|
||||
* bits. This would prevent bogus_page
|
||||
* replacement from working properly.
|
||||
*/
|
||||
vm_page_lock(m);
|
||||
vm_page_lock_queues();
|
||||
vm_page_clear_dirty(m, base, PAGE_SIZE - base);
|
||||
vm_page_unlock_queues();
|
||||
vm_page_unlock(m);
|
||||
} else if ((nsize & PAGE_MASK) &&
|
||||
__predict_false(object->cache != NULL)) {
|
||||
vm_page_cache_free(object, OFF_TO_IDX(nsize),
|
||||
@ -1071,15 +1069,12 @@ vnode_pager_putpages(object, m, count, sync, rtvals)
|
||||
* then delayed.
|
||||
*/
|
||||
int
|
||||
vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
struct vnode *vp;
|
||||
vm_page_t *m;
|
||||
int bytecount;
|
||||
int flags;
|
||||
int *rtvals;
|
||||
vnode_pager_generic_putpages(struct vnode *vp, vm_page_t *ma, int bytecount,
|
||||
int flags, int *rtvals)
|
||||
{
|
||||
int i;
|
||||
vm_object_t object;
|
||||
vm_page_t m;
|
||||
int count;
|
||||
|
||||
int maxsize, ncount;
|
||||
@ -1098,9 +1093,9 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
for (i = 0; i < count; i++)
|
||||
rtvals[i] = VM_PAGER_AGAIN;
|
||||
|
||||
if ((int64_t)m[0]->pindex < 0) {
|
||||
if ((int64_t)ma[0]->pindex < 0) {
|
||||
printf("vnode_pager_putpages: attempt to write meta-data!!! -- 0x%lx(%lx)\n",
|
||||
(long)m[0]->pindex, (u_long)m[0]->dirty);
|
||||
(long)ma[0]->pindex, (u_long)ma[0]->dirty);
|
||||
rtvals[0] = VM_PAGER_BAD;
|
||||
return VM_PAGER_BAD;
|
||||
}
|
||||
@ -1108,7 +1103,7 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
maxsize = count * PAGE_SIZE;
|
||||
ncount = count;
|
||||
|
||||
poffset = IDX_TO_OFF(m[0]->pindex);
|
||||
poffset = IDX_TO_OFF(ma[0]->pindex);
|
||||
|
||||
/*
|
||||
* If the page-aligned write is larger then the actual file we
|
||||
@ -1122,6 +1117,7 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
* We do not under any circumstances truncate the valid bits, as
|
||||
* this will screw up bogus page replacement.
|
||||
*/
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (maxsize + poffset > object->un_pager.vnp.vnp_size) {
|
||||
if (object->un_pager.vnp.vnp_size > poffset) {
|
||||
int pgoff;
|
||||
@ -1129,12 +1125,19 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
maxsize = object->un_pager.vnp.vnp_size - poffset;
|
||||
ncount = btoc(maxsize);
|
||||
if ((pgoff = (int)maxsize & PAGE_MASK) != 0) {
|
||||
vm_page_lock(m[ncount - 1]);
|
||||
vm_page_lock_queues();
|
||||
vm_page_clear_dirty(m[ncount - 1], pgoff,
|
||||
PAGE_SIZE - pgoff);
|
||||
vm_page_unlock_queues();
|
||||
vm_page_unlock(m[ncount - 1]);
|
||||
/*
|
||||
* If the object is locked and the following
|
||||
* conditions hold, then the page's dirty
|
||||
* field cannot be concurrently changed by a
|
||||
* pmap operation.
|
||||
*/
|
||||
m = ma[ncount - 1];
|
||||
KASSERT(m->busy > 0,
|
||||
("vnode_pager_generic_putpages: page %p is not busy", m));
|
||||
KASSERT((m->flags & PG_WRITEABLE) == 0,
|
||||
("vnode_pager_generic_putpages: page %p is not read-only", m));
|
||||
vm_page_clear_dirty(m, pgoff, PAGE_SIZE -
|
||||
pgoff);
|
||||
}
|
||||
} else {
|
||||
maxsize = 0;
|
||||
@ -1146,6 +1149,7 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
}
|
||||
}
|
||||
}
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
|
||||
/*
|
||||
* pageouts are already clustered, use IO_ASYNC t o force a bawrite()
|
||||
@ -1182,7 +1186,7 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
|
||||
if (auio.uio_resid) {
|
||||
if (ppscheck || ppsratecheck(&lastfail, &curfail, 1))
|
||||
printf("vnode_pager_putpages: residual I/O %zd at %lu\n",
|
||||
auio.uio_resid, (u_long)m[0]->pindex);
|
||||
auio.uio_resid, (u_long)ma[0]->pindex);
|
||||
}
|
||||
for (i = 0; i < ncount; i++) {
|
||||
rtvals[i] = VM_PAGER_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user