From: Martin Pieuchot Subject: uvm_fault_upper_lookup: delay pmap_extract() To: tech@openbsd.org Cc: tb@openbsd.org Date: Thu, 28 Nov 2024 10:01:15 +0100 uvm_fault_upper_lookup() enters existing neighbor pages found in the amap. Diff below reorder the checks in the loop to avoid calling the expensive pmap_extract(9) when there is no corresponding anon or if the page is PG_RELEASED|PG_BUSY and won't be entered anyway. While here call pmap_update() only if, at least, a page has been entered. ok? Index: uvm/uvm_fault.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_fault.c,v diff -u -p -r1.146 uvm_fault.c --- uvm/uvm_fault.c 27 Nov 2024 10:58:07 -0000 1.146 +++ uvm/uvm_fault.c 28 Nov 2024 08:35:10 -0000 @@ -841,10 +841,11 @@ uvm_fault_upper_lookup(struct uvm_faulti { 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_faulti 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_faulti 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_faulti * 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;