summaryrefslogtreecommitdiffstats
path: root/sys/i386/xen/pmap.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-09-06 10:30:11 +0000
committerkib <kib@FreeBSD.org>2011-09-06 10:30:11 +0000
commita9d505a22a9d9d343bf6874e995b921ad977453c (patch)
tree608b3b06589b15335451f37a8c8b11d1779e9a72 /sys/i386/xen/pmap.c
parenta6bb123606f7afa6fb3342b35dad217c76951ee3 (diff)
downloadFreeBSD-src-a9d505a22a9d9d343bf6874e995b921ad977453c.zip
FreeBSD-src-a9d505a22a9d9d343bf6874e995b921ad977453c.tar.gz
Split the vm_page flags PG_WRITEABLE and PG_REFERENCED into atomic
flags field. Updates to the atomic flags are performed using the atomic ops on the containing word, do not require any vm lock to be held, and are non-blocking. The vm_page_aflag_set(9) and vm_page_aflag_clear(9) functions are provided to modify afalgs. Document the changes to flags field to only require the page lock. Introduce vm_page_reference(9) function to provide a stable KPI and KBI for filesystems like tmpfs and zfs which need to mark a page as referenced. Reviewed by: alc, attilio Tested by: marius, flo (sparc64); andreast (powerpc, powerpc64) Approved by: re (bz)
Diffstat (limited to 'sys/i386/xen/pmap.c')
-rw-r--r--sys/i386/xen/pmap.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index ece1b6c..b19f75c 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -2037,7 +2037,7 @@ pmap_collect(pmap_t locked_pmap, struct vpgqueues *vpq)
KASSERT((tpte & PG_W) == 0,
("pmap_collect: wired pte %#jx", (uintmax_t)tpte));
if (tpte & PG_A)
- vm_page_flag_set(m, PG_REFERENCED);
+ vm_page_aflag_set(m, PGA_REFERENCED);
if ((tpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
vm_page_dirty(m);
free = NULL;
@@ -2050,7 +2050,7 @@ pmap_collect(pmap_t locked_pmap, struct vpgqueues *vpq)
PMAP_UNLOCK(pmap);
}
if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_flag_clear(m, PG_WRITEABLE);
+ vm_page_aflag_clear(m, PGA_WRITEABLE);
}
sched_unpin();
}
@@ -2222,7 +2222,7 @@ pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pmap_pvh_free(&m->md, pmap, va);
if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_flag_clear(m, PG_WRITEABLE);
+ vm_page_aflag_clear(m, PGA_WRITEABLE);
}
/*
@@ -2274,7 +2274,7 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, vm_page_t *free)
if ((oldpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
vm_page_dirty(m);
if (oldpte & PG_A)
- vm_page_flag_set(m, PG_REFERENCED);
+ vm_page_aflag_set(m, PGA_REFERENCED);
pmap_remove_entry(pmap, m, va);
}
return (pmap_unuse_pt(pmap, va, free));
@@ -2446,7 +2446,7 @@ pmap_remove_all(vm_page_t m)
if (tpte & PG_W)
pmap->pm_stats.wired_count--;
if (tpte & PG_A)
- vm_page_flag_set(m, PG_REFERENCED);
+ vm_page_aflag_set(m, PGA_REFERENCED);
/*
* Update the vm_page_t clean and reference bits.
@@ -2459,7 +2459,7 @@ pmap_remove_all(vm_page_t m)
free_pv_entry(pmap, pv);
PMAP_UNLOCK(pmap);
}
- vm_page_flag_clear(m, PG_WRITEABLE);
+ vm_page_aflag_clear(m, PGA_WRITEABLE);
PT_UPDATES_FLUSH();
if (*PMAP1)
PT_SET_MA(PADDR1, 0);
@@ -2739,7 +2739,7 @@ validate:
if ((prot & VM_PROT_WRITE) != 0) {
newpte |= PG_RW;
if ((newpte & PG_MANAGED) != 0)
- vm_page_flag_set(m, PG_WRITEABLE);
+ vm_page_aflag_set(m, PGA_WRITEABLE);
}
#ifdef PAE
if ((prot & VM_PROT_EXECUTE) == 0)
@@ -2764,7 +2764,7 @@ validate:
PT_SET_VA(pte, newpte | PG_A, FALSE);
if (origpte & PG_A) {
if (origpte & PG_MANAGED)
- vm_page_flag_set(om, PG_REFERENCED);
+ vm_page_aflag_set(om, PGA_REFERENCED);
if (opa != VM_PAGE_TO_PHYS(m))
invlva = TRUE;
#ifdef PAE
@@ -2781,7 +2781,7 @@ validate:
}
if ((origpte & PG_MANAGED) != 0 &&
TAILQ_EMPTY(&om->md.pv_list))
- vm_page_flag_clear(om, PG_WRITEABLE);
+ vm_page_aflag_clear(om, PGA_WRITEABLE);
if (invlva)
pmap_invalidate_page(pmap, va);
} else{
@@ -3549,7 +3549,7 @@ pmap_remove_pages(pmap_t pmap)
TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_flag_clear(m, PG_WRITEABLE);
+ vm_page_aflag_clear(m, PGA_WRITEABLE);
pmap_unuse_pt(pmap, pv->pv_va, &free);
@@ -3604,13 +3604,13 @@ pmap_is_modified(vm_page_t m)
rv = FALSE;
/*
- * If the page is not VPO_BUSY, then PG_WRITEABLE cannot be
- * concurrently set while the object is locked. Thus, if PG_WRITEABLE
+ * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be
+ * concurrently set while the object is locked. Thus, if PGA_WRITEABLE
* is clear, no PTEs can have PG_M set.
*/
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
if ((m->oflags & VPO_BUSY) == 0 &&
- (m->flags & PG_WRITEABLE) == 0)
+ (m->aflags & PGA_WRITEABLE) == 0)
return (rv);
vm_page_lock_queues();
sched_pin();
@@ -3735,13 +3735,13 @@ pmap_remove_write(vm_page_t m)
("pmap_remove_write: page %p is not managed", m));
/*
- * If the page is not VPO_BUSY, then PG_WRITEABLE cannot be set by
- * another thread while the object is locked. Thus, if PG_WRITEABLE
+ * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
+ * another thread while the object is locked. Thus, if PGA_WRITEABLE
* is clear, no page table entries need updating.
*/
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
if ((m->oflags & VPO_BUSY) == 0 &&
- (m->flags & PG_WRITEABLE) == 0)
+ (m->aflags & PGA_WRITEABLE) == 0)
return;
vm_page_lock_queues();
sched_pin();
@@ -3769,7 +3769,7 @@ retry:
}
PMAP_UNLOCK(pmap);
}
- vm_page_flag_clear(m, PG_WRITEABLE);
+ vm_page_aflag_clear(m, PGA_WRITEABLE);
PT_UPDATES_FLUSH();
if (*PMAP1)
PT_SET_MA(PADDR1, 0);
@@ -3846,11 +3846,11 @@ pmap_clear_modify(vm_page_t m)
("pmap_clear_modify: page %p is busy", m));
/*
- * If the page is not PG_WRITEABLE, then no PTEs can have PG_M set.
+ * If the page is not PGA_WRITEABLE, then no PTEs can have PG_M set.
* If the object containing the page is locked and the page is not
- * VPO_BUSY, then PG_WRITEABLE cannot be concurrently set.
+ * VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.
*/
- if ((m->flags & PG_WRITEABLE) == 0)
+ if ((m->aflags & PGA_WRITEABLE) == 0)
return;
vm_page_lock_queues();
sched_pin();
OpenPOWER on IntegriCloud