summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2022-10-25 18:44:37 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2022-10-25 18:44:37 +0000
commitbef72fef14fad63dfd95083c9810cfb5daf47a5f (patch)
treeb650c68561b48e4a34534421888df00b7fd707c1 /sys
parente21db289cf38e7ab420822d8fa2bf93ce821b913 (diff)
Store mod/ref flags using md pg_flags values rather than a specific field in
vm_page_md, which allows this struct to shrink a bit.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hppa/hppa/pmap.c53
-rw-r--r--sys/arch/hppa/include/pmap.h13
2 files changed, 38 insertions, 28 deletions
diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c
index 657dfffa362..a6d12b5af4c 100644
--- a/sys/arch/hppa/hppa/pmap.c
+++ b/sys/arch/hppa/hppa/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.178 2022/09/10 20:35:28 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.179 2022/10/25 18:44:36 miod Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -101,8 +101,16 @@ u_int hppa_prot[8];
#define pmap_sid(pmap, va) \
(((va & 0xc0000000) != 0xc0000000)? pmap->pmap_space : HPPA_SID_KERNEL)
-#define pmap_pvh_attrs(a) \
- (((a) & PTE_PROT(TLB_DIRTY)) | ((a) ^ PTE_PROT(TLB_REFTRAP)))
+static inline int
+pmap_pvh_attrs(pt_entry_t pte)
+{
+ int attrs = 0;
+ if (pte & PTE_PROT(TLB_DIRTY))
+ attrs |= PG_PMAP_MOD;
+ if ((pte & PTE_PROT(TLB_REFTRAP)) == 0)
+ attrs |= PG_PMAP_REF;
+ return attrs;
+}
struct vm_page *pmap_pagealloc(struct uvm_object *obj, voff_t off);
void pmap_pte_flush(struct pmap *pmap, vaddr_t va, pt_entry_t pte);
@@ -779,9 +787,7 @@ pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
if (pg != NULL) {
pve = pmap_pv_remove(pg, pmap, va);
- mtx_enter(&pg->mdpage.pvh_mtx);
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- mtx_leave(&pg->mdpage.pvh_mtx);
+ atomic_setbits_int(&pg->pg_flags, pmap_pvh_attrs(pte));
}
} else {
DPRINTF(PDB_ENTER,
@@ -869,9 +875,8 @@ pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva)
if (pmap_initialized &&
(pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
- mtx_enter(&pg->mdpage.pvh_mtx);
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- mtx_leave(&pg->mdpage.pvh_mtx);
+ atomic_setbits_int(&pg->pg_flags,
+ pmap_pvh_attrs(pte));
if ((pve = pmap_pv_remove(pg, pmap, sva)))
pmap_pv_free(pve);
} else {
@@ -925,9 +930,8 @@ pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
if (pg != NULL) {
- mtx_enter(&pg->mdpage.pvh_mtx);
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- mtx_leave(&pg->mdpage.pvh_mtx);
+ atomic_setbits_int(&pg->pg_flags,
+ pmap_pvh_attrs(pte));
}
pmap_pte_flush(pmap, sva, pte);
@@ -977,8 +981,8 @@ pmap_page_remove(struct vm_page *pg)
pmap_destroy(pmap);
pmap_pv_free(pve);
+ atomic_setbits_int(&pg->pg_flags, attrs);
mtx_enter(&pg->mdpage.pvh_mtx);
- pg->mdpage.pvh_attrs |= attrs;
}
mtx_leave(&pg->mdpage.pvh_mtx);
@@ -1018,12 +1022,14 @@ pmap_changebit(struct vm_page *pg, u_int set, u_int clear)
{
struct pv_entry *pve;
pt_entry_t res;
+ int attrs;
DPRINTF(PDB_FOLLOW|PDB_BITS,
("pmap_changebit(%p, %x, %x)\n", pg, set, clear));
+ res = 0;
+ attrs = 0;
mtx_enter(&pg->mdpage.pvh_mtx);
- res = pg->mdpage.pvh_attrs = 0;
for (pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next) {
struct pmap *pmap = pve->pv_pmap;
vaddr_t va = pve->pv_va;
@@ -1041,7 +1047,7 @@ pmap_changebit(struct vm_page *pg, u_int set, u_int clear)
#endif
pte &= ~clear;
pte |= set;
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ attrs |= pmap_pvh_attrs(pte);
res |= pmap_pvh_attrs(opte);
if (opte != pte) {
@@ -1051,12 +1057,17 @@ pmap_changebit(struct vm_page *pg, u_int set, u_int clear)
}
}
mtx_leave(&pg->mdpage.pvh_mtx);
+ if (attrs != (PG_PMAP_REF | PG_PMAP_MOD))
+ atomic_clearbits_int(&pg->pg_flags,
+ attrs ^(PG_PMAP_REF | PG_PMAP_MOD));
+ if (attrs != 0)
+ atomic_setbits_int(&pg->pg_flags, attrs);
return ((res & (clear | set)) != 0);
}
boolean_t
-pmap_testbit(struct vm_page *pg, u_int bit)
+pmap_testbit(struct vm_page *pg, int bit)
{
struct pv_entry *pve;
pt_entry_t pte;
@@ -1065,13 +1076,13 @@ pmap_testbit(struct vm_page *pg, u_int bit)
DPRINTF(PDB_FOLLOW|PDB_BITS, ("pmap_testbit(%p, %x)\n", pg, bit));
mtx_enter(&pg->mdpage.pvh_mtx);
- for (pve = pg->mdpage.pvh_list; !(pg->mdpage.pvh_attrs & bit) && pve;
+ for (pve = pg->mdpage.pvh_list; !(pg->pg_flags & bit) && pve;
pve = pve->pv_next) {
pte = pmap_vp_find(pve->pv_pmap, pve->pv_va);
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ atomic_setbits_int(&pg->pg_flags, pmap_pvh_attrs(pte));
}
- ret = ((pg->mdpage.pvh_attrs & bit) != 0);
mtx_leave(&pg->mdpage.pvh_mtx);
+ ret = ((pg->pg_flags & bit) != 0);
return ret;
}
@@ -1231,9 +1242,7 @@ pmap_kremove(vaddr_t va, vsize_t size)
pmap_pte_flush(pmap_kernel(), va, pte);
pmap_pte_set(pde, va, 0);
if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
- mtx_enter(&pg->mdpage.pvh_mtx);
- pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- mtx_leave(&pg->mdpage.pvh_mtx);
+ atomic_setbits_int(&pg->pg_flags, pmap_pvh_attrs(pte));
/* just in case we have enter/kenter mismatch */
if ((pve = pmap_pv_remove(pg, pmap_kernel(), va)))
pmap_pv_free(pve);
diff --git a/sys/arch/hppa/include/pmap.h b/sys/arch/hppa/include/pmap.h
index dd9bc6475d8..3177608e3c0 100644
--- a/sys/arch/hppa/include/pmap.h
+++ b/sys/arch/hppa/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.51 2015/07/27 03:36:38 guenther Exp $ */
+/* $OpenBSD: pmap.h,v 1.52 2022/10/25 18:44:36 miod Exp $ */
/*
* Copyright (c) 2002-2004 Michael Shalayeff
@@ -112,17 +112,20 @@ pmap_prefer(vaddr_t offs, vaddr_t hint)
#define pmap_update(pm) (void)(pm)
#define pmap_copy(dpmap,spmap,da,len,sa)
+#define PG_PMAP_MOD PG_PMAP0 /* modified */
+#define PG_PMAP_REF PG_PMAP1 /* referenced */
+
#define pmap_clear_modify(pg) pmap_changebit(pg, 0, PTE_PROT(TLB_DIRTY))
#define pmap_clear_reference(pg) pmap_changebit(pg, PTE_PROT(TLB_REFTRAP), 0)
-#define pmap_is_modified(pg) pmap_testbit(pg, PTE_PROT(TLB_DIRTY))
-#define pmap_is_referenced(pg) pmap_testbit(pg, PTE_PROT(TLB_REFTRAP))
+#define pmap_is_modified(pg) pmap_testbit(pg, PG_PMAP_MOD)
+#define pmap_is_referenced(pg) pmap_testbit(pg, PG_PMAP_REF)
#define pmap_unuse_final(p) /* nothing */
#define pmap_remove_holes(vm) do { /* nothing */ } while (0)
void pmap_bootstrap(vaddr_t);
boolean_t pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t);
-boolean_t pmap_testbit(struct vm_page *, pt_entry_t);
+boolean_t pmap_testbit(struct vm_page *, int);
void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva);
void pmap_page_remove(struct vm_page *pg);
@@ -163,13 +166,11 @@ struct pv_entry;
struct vm_page_md {
struct mutex pvh_mtx;
struct pv_entry *pvh_list; /* head of list (locked by pvh_mtx) */
- u_int pvh_attrs; /* to preserve ref/mod */
};
#define VM_MDPAGE_INIT(pg) do { \
mtx_init(&(pg)->mdpage.pvh_mtx, IPL_VM); \
(pg)->mdpage.pvh_list = NULL; \
- (pg)->mdpage.pvh_attrs = 0; \
} while (0)
#endif