diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2024-11-29 06:40:58 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2024-11-29 06:40:58 +0000 |
commit | 9c7efc533db2463910fb2e43f82ac6130f383b2c (patch) | |
tree | c5419c42bf834f418e951b0212c2796adacbf0c1 | |
parent | a32e86db3da9dd846f8da68c624aed8951025c0a (diff) |
When paging ahead, delay calling pmap_extract() after checking for a valid page.
While here call pmap_update() only if, at least, a page has been entered.
ok tb@, kettenis@
-rw-r--r-- | sys/uvm/uvm_fault.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c index 216b1a83efa..7b7bded5453 100644 --- a/sys/uvm/uvm_fault.c +++ b/sys/uvm/uvm_fault.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_fault.c,v 1.146 2024/11/27 10:58:07 mpi Exp $ */ +/* $OpenBSD: uvm_fault.c,v 1.147 2024/11/29 06:40:57 mpi Exp $ */ /* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */ /* @@ -841,10 +841,11 @@ uvm_fault_upper_lookup(struct uvm_faultinfo *ufi, { struct vm_amap *amap = ufi->entry->aref.ar_amap; struct vm_anon *anon; + struct vm_page *pg; boolean_t shadowed; vaddr_t currva; paddr_t pa; - int lcv; + int lcv, entered = 0; /* locked: maps(read), amap(if there) */ KASSERT(amap == NULL || @@ -859,16 +860,6 @@ uvm_fault_upper_lookup(struct uvm_faultinfo *ufi, shadowed = FALSE; for (lcv = 0; lcv < flt->npages; lcv++, currva += PAGE_SIZE) { /* - * dont play with VAs that are already mapped - * except for center) - */ - if (lcv != flt->centeridx && - pmap_extract(ufi->orig_map->pmap, currva, &pa)) { - pages[lcv] = PGO_DONTCARE; - continue; - } - - /* * unmapped or center page. check if any anon at this level. */ if (amap == NULL || anons[lcv] == NULL) { @@ -884,12 +875,20 @@ uvm_fault_upper_lookup(struct uvm_faultinfo *ufi, shadowed = TRUE; continue; } + anon = anons[lcv]; + pg = anon->an_page; + KASSERT(anon->an_lock == amap->am_lock); - if (anon->an_page && - (anon->an_page->pg_flags & (PG_RELEASED|PG_BUSY)) == 0) { + + /* + * ignore busy pages. + * don't play with VAs that are already mapped. + */ + if (pg && (pg->pg_flags & (PG_RELEASED|PG_BUSY)) == 0 && + !pmap_extract(ufi->orig_map->pmap, currva, &pa)) { uvm_lock_pageq(); - uvm_pageactivate(anon->an_page); /* reactivate */ + uvm_pageactivate(pg); /* reactivate */ uvm_unlock_pageq(); counters_inc(uvmexp_counters, flt_namap); @@ -902,13 +901,14 @@ uvm_fault_upper_lookup(struct uvm_faultinfo *ufi, * that we enter these right now. */ (void) pmap_enter(ufi->orig_map->pmap, currva, - VM_PAGE_TO_PHYS(anon->an_page) | flt->pa_flags, + VM_PAGE_TO_PHYS(pg) | flt->pa_flags, (anon->an_ref > 1) ? (flt->enter_prot & ~PROT_WRITE) : flt->enter_prot, PMAP_CANFAIL); + entered++; } } - if (flt->npages > 1) + if (entered > 0) pmap_update(ufi->orig_map->pmap); return shadowed; |