On 16/02/21(Tue) 11:20, Martin Pieuchot wrote:
> Start by moving `pgo_fault' handler outside of uvm_fault_lower().
> 
> If a page has a backing object that prefer to handler to fault itself
> the locking will be different, so keep it under KERNEL_LOCK() for the
> moment and make it separate from the rest of uvm_fault_lower().
> 
> ok?

Anyone?

> 
> Index: uvm/uvm_fault.c
> ===================================================================
> RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
> retrieving revision 1.115
> diff -u -p -r1.115 uvm_fault.c
> --- uvm/uvm_fault.c   16 Feb 2021 09:10:17 -0000      1.115
> +++ uvm/uvm_fault.c   16 Feb 2021 10:13:58 -0000
> @@ -598,10 +598,37 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
>                       /* case 1: fault on an anon in our amap */
>                       error = uvm_fault_upper(&ufi, &flt, anons, fault_type);
>               } else {
> -                     /* case 2: fault on backing object or zero fill */
> -                     KERNEL_LOCK();
> -                     error = uvm_fault_lower(&ufi, &flt, pages, fault_type);
> -                     KERNEL_UNLOCK();
> +                     struct uvm_object *uobj = ufi.entry->object.uvm_obj;
> +
> +                     /*
> +                      * 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 prefer to handle the fault
> +                      * itself (rather than letting us do it with the usual
> +                      * pgo_get hook).  the backing object signals this by
> +                      * providing a pgo_fault routine.
> +                      */
> +                     if (uobj != NULL && uobj->pgops->pgo_fault != NULL) {
> +                             KERNEL_LOCK();
> +                             error = uobj->pgops->pgo_fault(&ufi,
> +                                 flt.startva, pages, flt.npages,
> +                                 flt.centeridx, fault_type, flt.access_type,
> +                                 PGO_LOCKED);
> +                             KERNEL_UNLOCK();
> +
> +                             if (error == VM_PAGER_OK)
> +                                     error = 0;
> +                             else if (error == VM_PAGER_REFAULT)
> +                                     error = ERESTART;
> +                             else
> +                                     error = EACCES;
> +                     } else {
> +                             /* case 2: fault on backing obj or zero fill */
> +                             KERNEL_LOCK();
> +                             error = uvm_fault_lower(&ufi, &flt, pages,
> +                                 fault_type);
> +                             KERNEL_UNLOCK();
> +                     }
>               }
>       }
>  
> @@ -1054,26 +1081,6 @@ uvm_fault_lower(struct uvm_faultinfo *uf
>       struct vm_anon *anon = NULL;
>       vaddr_t currva;
>       voff_t uoff;
> -
> -     /*
> -      * 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
> -      * prefer to handle the fault itself (rather than letting us do it
> -      * with the usual pgo_get hook).  the backing object signals this by
> -      * providing a pgo_fault routine.
> -      */
> -     if (uobj != NULL && uobj->pgops->pgo_fault != NULL) {
> -             result = uobj->pgops->pgo_fault(ufi, flt->startva, pages,
> -                 flt->npages, flt->centeridx, fault_type, flt->access_type,
> -                 PGO_LOCKED);
> -
> -             if (result == VM_PAGER_OK)
> -                     return (0);             /* pgo_fault did pmap enter */
> -             else if (result == VM_PAGER_REFAULT)
> -                     return ERESTART;        /* try again! */
> -             else
> -                     return (EACCES);
> -     }
>  
>       /*
>        * now, if the desired page is not shadowed by the amap and we have
> 

Reply via email to