> Date: Fri, 13 Nov 2020 08:19:03 -0300
> From: Martin Pieuchot <[email protected]>
> 
> On 04/11/20(Wed) 11:04, Martin Pieuchot wrote:
> > Diff below introduces a helper that looks for existing mapping.  The
> > value returned by this lookup function determines if there's an anon
> > at the faulting address which tells us if we're dealign with a fault
> > of type 1 or 2.
> > 
> > This small refactoring is part of the current work to separate the code
> > handling faults of type 1 and 2.  The end goal being to move the type 1
> > faults handling out of the KERNEL_LOCK().
> > 
> > The function name is taken from NetBSD to not introduce more difference
> > than there's already.
> 
> New diff now that the other one has been committed, ok?

ok kettenis@

> Index: uvm/uvm_fault.c
> ===================================================================
> RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
> retrieving revision 1.105
> diff -u -p -r1.105 uvm_fault.c
> --- uvm/uvm_fault.c   13 Nov 2020 11:16:08 -0000      1.105
> +++ uvm/uvm_fault.c   13 Nov 2020 11:17:52 -0000
> @@ -801,6 +801,84 @@ uvm_fault_upper(struct uvm_faultinfo *uf
>       return 0;
>  }
>  
> +
> +/*
> + * uvm_fault_upper_lookup: look up existing h/w mapping and amap.
> + *
> + * iterate range of interest:
> + *      1. check if h/w mapping exists.  if yes, we don't care
> + *      2. check if anon exists.  if not, page is lower.
> + *      3. if anon exists, enter h/w mapping for neighbors.
> + */
> +boolean_t
> +uvm_fault_upper_lookup(struct uvm_faultinfo *ufi,
> +    const struct uvm_faultctx *flt, struct vm_anon **anons,
> +    struct vm_page **pages)
> +{
> +     struct vm_amap *amap = ufi->entry->aref.ar_amap;
> +     struct vm_anon *anon;
> +     boolean_t shadowed;
> +     vaddr_t currva;
> +     paddr_t pa;
> +     int lcv;
> +
> +     /*
> +      * map in the backpages and frontpages we found in the amap in hopes
> +      * of preventing future faults.    we also init the pages[] array as
> +      * we go.
> +      */
> +     currva = flt->startva;
> +     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) {
> +                     pages[lcv] = NULL;
> +                     continue;
> +             }
> +
> +             /* check for present page and map if possible. re-activate it */
> +             pages[lcv] = PGO_DONTCARE;
> +             if (lcv == flt->centeridx) {    /* save center for later! */
> +                     shadowed = TRUE;
> +                     continue;
> +             }
> +             anon = anons[lcv];
> +             if (anon->an_page &&
> +                 (anon->an_page->pg_flags & (PG_RELEASED|PG_BUSY)) == 0) {
> +                     uvm_lock_pageq();
> +                     uvm_pageactivate(anon->an_page);        /* reactivate */
> +                     uvm_unlock_pageq();
> +                     uvmexp.fltnamap++;
> +
> +                     /*
> +                      * Since this isn't the page that's actually faulting,
> +                      * ignore pmap_enter() failures; it's not critical
> +                      * that we enter these right now.
> +                      */
> +                     (void) pmap_enter(ufi->orig_map->pmap, currva,
> +                         VM_PAGE_TO_PHYS(anon->an_page) | flt->pa_flags,
> +                         (anon->an_ref > 1) ?
> +                         (flt->enter_prot & ~PROT_WRITE) : flt->enter_prot,
> +                         PMAP_CANFAIL |
> +                          (VM_MAPENT_ISWIRED(ufi->entry) ? PMAP_WIRED : 0));
> +             }
> +     }
> +     if (flt->npages > 1)
> +             pmap_update(ufi->orig_map->pmap);
> +
> +     return shadowed;
> +}
> +
>  /*
>   *   F A U L T   -   m a i n   e n t r y   p o i n t
>   */
> @@ -827,7 +905,6 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
>       int result, lcv, gotpages;
>       vaddr_t currva;
>       voff_t uoff;
> -     paddr_t pa;
>       struct vm_amap *amap;
>       struct uvm_object *uobj;
>       struct vm_anon *anons_store[UVM_MAXRANGE], **anons, *anon;
> @@ -868,61 +945,9 @@ ReFault:
>       amap = ufi.entry->aref.ar_amap;
>       uobj = ufi.entry->object.uvm_obj;
>  
> -     /*
> -      * map in the backpages and frontpages we found in the amap in hopes
> -      * of preventing future faults.    we also init the pages[] array as
> -      * we go.
> -      */
> -     currva = flt.startva;
> -     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) {
> -                     pages[lcv] = NULL;
> -                     continue;
> -             }
> -
> -             /* check for present page and map if possible.   re-activate 
> it. */
> -             pages[lcv] = PGO_DONTCARE;
> -             if (lcv == flt.centeridx) {     /* save center for later! */
> -                     shadowed = TRUE;
> -                     continue;
> -             }
> -             anon = anons[lcv];
> -             if (anon->an_page &&
> -                 (anon->an_page->pg_flags & (PG_RELEASED|PG_BUSY)) == 0) {
> -                     uvm_lock_pageq();
> -                     uvm_pageactivate(anon->an_page);        /* reactivate */
> -                     uvm_unlock_pageq();
> -                     uvmexp.fltnamap++;
> -
> -                     /*
> -                      * Since this isn't the page that's actually faulting,
> -                      * ignore pmap_enter() failures; it's not critical
> -                      * that we enter these right now.
> -                      */
> -                     (void) pmap_enter(ufi.orig_map->pmap, currva,
> -                         VM_PAGE_TO_PHYS(anon->an_page) | flt.pa_flags,
> -                         (anon->an_ref > 1) ?
> -                         (flt.enter_prot & ~PROT_WRITE) : flt.enter_prot,
> -                         PMAP_CANFAIL |
> -                          (VM_MAPENT_ISWIRED(ufi.entry) ? PMAP_WIRED : 0));
> -             }
> -     }
> -     if (flt.npages > 1)
> -             pmap_update(ufi.orig_map->pmap);
> -
>       /* (shadowed == TRUE) if there is an anon at the faulting address */
> +     shadowed = uvm_fault_upper_lookup(&ufi, &flt, anons, pages);
> +
>       /*
>        * if the desired page is not shadowed by the amap and we have a
>        * backing object, then we check to see if the backing object would
> 
> 

Reply via email to