Hi,
Can we convert the pv_entry list in amd64 pmap into an SLIST?
I think the code with macros is easier to read.
ok?
bluhm
Index: arch/amd64//amd64/pmap.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/pmap.c,v
retrieving revision 1.141
diff -u -p -r1.141 pmap.c
--- arch/amd64//amd64/pmap.c 16 Dec 2020 21:11:35 -0000 1.141
+++ arch/amd64//amd64/pmap.c 16 Dec 2020 21:13:40 -0000
@@ -321,9 +321,9 @@ void pmap_remove_ept(struct pmap *, vadd
void pmap_do_remove_ept(struct pmap *, vaddr_t);
int pmap_enter_ept(struct pmap *, vaddr_t, paddr_t, vm_prot_t);
int pmap_remove_pte(struct pmap *, struct vm_page *, pt_entry_t *,
- vaddr_t, int, struct pv_entry **);
+ vaddr_t, int, struct pvlist *);
void pmap_remove_ptes(struct pmap *, struct vm_page *, vaddr_t,
- vaddr_t, vaddr_t, int, struct pv_entry **);
+ vaddr_t, vaddr_t, int, struct pvlist *);
#define PMAP_REMOVE_ALL 0 /* remove all mappings */
#define PMAP_REMOVE_SKIPWIRED 1 /* skip wired mappings */
@@ -1029,8 +1029,7 @@ pmap_enter_pv(struct vm_page *pg, struct
pve->pv_va = va;
pve->pv_ptp = ptp; /* NULL for kernel pmap */
mtx_enter(&pg->mdpage.pv_mtx);
- pve->pv_next = pg->mdpage.pv_list; /* add to ... */
- pg->mdpage.pv_list = pve; /* ... list */
+ SLIST_INSERT_HEAD(&pg->mdpage.pv_list, pve, pv_next);
mtx_leave(&pg->mdpage.pv_mtx);
}
@@ -1044,16 +1043,19 @@ pmap_enter_pv(struct vm_page *pg, struct
struct pv_entry *
pmap_remove_pv(struct vm_page *pg, struct pmap *pmap, vaddr_t va)
{
- struct pv_entry *pve, **prevptr;
+ struct pv_entry *pve, *prev;
mtx_enter(&pg->mdpage.pv_mtx);
- prevptr = &pg->mdpage.pv_list;
- while ((pve = *prevptr) != NULL) {
+ prev = NULL;
+ SLIST_FOREACH(pve, &pg->mdpage.pv_list, pv_next) {
if (pve->pv_pmap == pmap && pve->pv_va == va) { /* match? */
- *prevptr = pve->pv_next; /* remove it! */
+ if (prev == NULL)
+ SLIST_REMOVE_HEAD(&pg->mdpage.pv_list, pv_next);
+ else
+ SLIST_REMOVE_AFTER(prev, pv_next);
break;
}
- prevptr = &pve->pv_next; /* previous pointer */
+ prev = pve; /* previous pointer */
}
mtx_leave(&pg->mdpage.pv_mtx);
return(pve); /* return removed pve */
@@ -1583,7 +1585,7 @@ pmap_copy_page(struct vm_page *srcpg, st
void
pmap_remove_ptes(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva,
- vaddr_t startva, vaddr_t endva, int flags, struct pv_entry **free_pvs)
+ vaddr_t startva, vaddr_t endva, int flags, struct pvlist *free_pvs)
{
struct pv_entry *pve;
pt_entry_t *pte = (pt_entry_t *) ptpva;
@@ -1643,10 +1645,8 @@ pmap_remove_ptes(struct pmap *pmap, stru
/* sync R/M bits */
pmap_sync_flags_pte(pg, opte);
pve = pmap_remove_pv(pg, pmap, startva);
- if (pve != NULL) {
- pve->pv_next = *free_pvs;
- *free_pvs = pve;
- }
+ if (pve != NULL)
+ SLIST_INSERT_HEAD(free_pvs, pve, pv_next);
/* end of "for" loop: time for next pte */
}
@@ -1663,7 +1663,7 @@ pmap_remove_ptes(struct pmap *pmap, stru
int
pmap_remove_pte(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte,
- vaddr_t va, int flags, struct pv_entry **free_pvs)
+ vaddr_t va, int flags, struct pvlist *free_pvs)
{
struct pv_entry *pve;
struct vm_page *pg;
@@ -1708,10 +1708,8 @@ pmap_remove_pte(struct pmap *pmap, struc
/* sync R/M bits */
pmap_sync_flags_pte(pg, opte);
pve = pmap_remove_pv(pg, pmap, va);
- if (pve != NULL) {
- pve->pv_next = *free_pvs;
- *free_pvs = pve;
- }
+ if (pve != NULL)
+ SLIST_INSERT_HEAD(free_pvs, pve, pv_next);
return 1;
}
@@ -1746,7 +1744,7 @@ pmap_do_remove(struct pmap *pmap, vaddr_
vaddr_t blkendva;
struct vm_page *ptp;
struct pv_entry *pve;
- struct pv_entry *free_pvs = NULL;
+ struct pvlist free_pvs = SLIST_HEAD_INITIALIZER(pvlist);
vaddr_t va;
int shootall = 0, shootself;
struct pg_to_free empty_ptps;
@@ -1864,8 +1862,8 @@ pmap_do_remove(struct pmap *pmap, vaddr_
pmap_tlb_shootwait();
cleanup:
- while ((pve = free_pvs) != NULL) {
- free_pvs = pve->pv_next;
+ while ((pve = SLIST_FIRST(&free_pvs)) != NULL) {
+ SLIST_REMOVE_HEAD(&free_pvs, pv_next);
pool_put(&pmap_pv_pool, pve);
}
@@ -1898,7 +1896,7 @@ pmap_page_remove(struct vm_page *pg)
TAILQ_INIT(&empty_ptps);
mtx_enter(&pg->mdpage.pv_mtx);
- while ((pve = pg->mdpage.pv_list) != NULL) {
+ while ((pve = SLIST_FIRST(&pg->mdpage.pv_list)) != NULL) {
pmap_reference(pve->pv_pmap);
pm = pve->pv_pmap;
mtx_leave(&pg->mdpage.pv_mtx);
@@ -1917,8 +1915,8 @@ pmap_page_remove(struct vm_page *pg)
* again.
*/
mtx_enter(&pg->mdpage.pv_mtx);
- if ((pve = pg->mdpage.pv_list) == NULL ||
- pve->pv_pmap != pm) {
+ pve = SLIST_FIRST(&pg->mdpage.pv_list);
+ if (pve == NULL || pve->pv_pmap != pm) {
mtx_leave(&pg->mdpage.pv_mtx);
pmap_unmap_ptes(pm, scr3); /* unlocks pmap */
pmap_destroy(pm);
@@ -1926,7 +1924,7 @@ pmap_page_remove(struct vm_page *pg)
continue;
}
- pg->mdpage.pv_list = pve->pv_next;
+ SLIST_REMOVE_HEAD(&pg->mdpage.pv_list, pv_next);
mtx_leave(&pg->mdpage.pv_mtx);
#ifdef DIAGNOSTIC
@@ -2003,8 +2001,9 @@ pmap_test_attrs(struct vm_page *pg, unsi
mybits = 0;
mtx_enter(&pg->mdpage.pv_mtx);
- for (pve = pg->mdpage.pv_list; pve != NULL && mybits == 0;
- pve = pve->pv_next) {
+ SLIST_FOREACH(pve, &pg->mdpage.pv_list, pv_next) {
+ if (mybits != 0)
+ break;
level = pmap_find_pte_direct(pve->pv_pmap, pve->pv_va, &ptes,
&offs);
mybits |= (ptes[offs] & testbits);
@@ -2040,7 +2039,7 @@ pmap_clear_attrs(struct vm_page *pg, uns
atomic_clearbits_int(&pg->pg_flags, clearflags);
mtx_enter(&pg->mdpage.pv_mtx);
- for (pve = pg->mdpage.pv_list; pve != NULL; pve = pve->pv_next) {
+ SLIST_FOREACH(pve, &pg->mdpage.pv_list, pv_next) {
level = pmap_find_pte_direct(pve->pv_pmap, pve->pv_va, &ptes,
&offs);
opte = ptes[offs];
Index: arch/amd64//include/pmap.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/include/pmap.h,v
retrieving revision 1.77
diff -u -p -r1.77 pmap.h
--- arch/amd64//include/pmap.h 24 Jan 2020 05:27:32 -0000 1.77
+++ arch/amd64//include/pmap.h 16 Dec 2020 21:13:40 -0000
@@ -337,7 +337,7 @@ struct pmap {
* which it is mapped at.
*/
struct pv_entry { /* locked by its list's pvh_lock */
- struct pv_entry *pv_next; /* next entry */
+ SLIST_ENTRY(pv_entry) pv_next; /* next entry */
struct pmap *pv_pmap; /* the pmap */
vaddr_t pv_va; /* the virtual address */
struct vm_page *pv_ptp; /* the vm_page of the PTP */
@@ -524,14 +524,15 @@ kvtopte(vaddr_t va)
#ifndef _LOCORE
struct pv_entry;
+SLIST_HEAD(pvlist, pv_entry);
struct vm_page_md {
struct mutex pv_mtx;
- struct pv_entry *pv_list;
+ struct pvlist pv_list;
};
#define VM_MDPAGE_INIT(pg) do { \
mtx_init(&(pg)->mdpage.pv_mtx, IPL_VM); \
- (pg)->mdpage.pv_list = NULL; \
+ SLIST_INIT(&(pg)->mdpage.pv_list); \
} while (0)
#endif /* !_LOCORE */