> On Mar 14, 2019, at 10:27 AM, Robert Elz <k...@munnari.oz.au> wrote:
> 
>    Date:        Thu, 14 Mar 2019 08:06:58 -0700
>    From:        Jason Thorpe <thor...@me.com>
>    Message-ID:  <134778ad-a675-414a-bbb3-7eeeaf2c2...@me.com>
> 
>  | Great sleuthing, you pretty much nailed it.
> 
> OK, great.    This is the patch I plan to commit soon (rather than
> waiting on lots of review - so that the b5 tests can start working
> again ASAP).
> 
> If anyone has any issues with this, please make them known soon
> (as in quite soon...)

Looks good to me.  This is probably worth pulling up to netbsd-8 as well.

> Also, after this patch, I tested address wraparround (addr+llen < addr)
> and get the ENOMEM error that the patch returns (which seems to be the
> error that POSIX specifies for this kind of thing.   Ans speaking of which
> we appear to differ with POSIX in several error codes,  POSIX does not use
> EINVAL for mlock/munlock of a region which crosses a "hole" that would be
> ENOMEM (munlock converts the internal EINVAL into ENOMEM before returning,
> mlock() doesn't), and munlock() without a preceding mlock is not an error
> at all (POSIX says "regardless of how many times mlock( ) has been called by
> the process for any of the pages in the specified range."  Zero is a
> number of times that mlock() might have been called.   ALso, EAGAIN is
> correct for mlock() when the max number of pages the kernel will allow
> to be locked have been locked, but not for the case when a process exceeds
> its resource limit of locked pages ... that should be ENOMEM.   There
> might be more like this.   This patch doesn't do anything with those
> issues, they're not urgent, and we can fix them anytime (if we agree to
> do so.)

Yes, we should fix the error return cases as well.

> 
> kre
> 
> Index: uvm_map.c
> ===================================================================
> RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v
> retrieving revision 1.358
> diff -u -r1.358 uvm_map.c
> --- uvm_map.c 3 Mar 2019 17:37:36 -0000       1.358
> +++ uvm_map.c 14 Mar 2019 16:29:57 -0000
> @@ -3359,6 +3359,14 @@
>       }
>       entry = start_entry;
> 
> +     if (start == end) {             /* nothing required */
> +             if ((lockflags & UVM_LK_EXIT) == 0)
> +                     vm_map_unlock(map);
> +
> +             UVMHIST_LOG(maphist,"<- done (nothing)",0,0,0,0);
> +             return 0;
> +     }
> +
>       /*
>        * handle wiring and unwiring separately.
>        */
> Index: uvm_mmap.c
> ===================================================================
> RCS file: /cvsroot/src/sys/uvm/uvm_mmap.c,v
> retrieving revision 1.169
> diff -u -r1.169 uvm_mmap.c
> --- uvm_mmap.c        19 Dec 2017 18:34:47 -0000      1.169
> +++ uvm_mmap.c        14 Mar 2019 16:29:58 -0000
> @@ -759,8 +759,12 @@
> 
>       pageoff = (addr & PAGE_MASK);
>       addr -= pageoff;
> -     size += pageoff;
> -     size = (vsize_t)round_page(size);
> +     if (size != 0) {
> +             size += pageoff;
> +             size = (vsize_t)round_page(size);
> +     }
> +     if (addr + size < addr)
> +             return ENOMEM;
> 
>       error = range_test(&p->p_vmspace->vm_map, addr, size, false);
>       if (error)
> @@ -810,8 +814,12 @@
> 
>       pageoff = (addr & PAGE_MASK);
>       addr -= pageoff;
> -     size += pageoff;
> -     size = (vsize_t)round_page(size);
> +     if (size != 0) {
> +             size += pageoff;
> +             size = (vsize_t)round_page(size);
> +     }
> +     if (addr + size < addr)
> +             return ENOMEM;
> 
>       error = range_test(&p->p_vmspace->vm_map, addr, size, false);
>       if (error)
> Index: uvm_page.c
> ===================================================================
> RCS file: /cvsroot/src/sys/uvm/uvm_page.c,v
> retrieving revision 1.198
> diff -u -r1.198 uvm_page.c
> --- uvm_page.c        19 May 2018 15:03:26 -0000      1.198
> +++ uvm_page.c        14 Mar 2019 16:29:58 -0000
> @@ -1605,9 +1605,11 @@
> uvm_pageunwire(struct vm_page *pg)
> {
>       KASSERT(mutex_owned(&uvm_pageqlock));
> +     KASSERT(pg->wire_count != 0);
>       pg->wire_count--;
>       if (pg->wire_count == 0) {
>               uvm_pageactivate(pg);
> +             KASSERT(uvmexp.wired != 0);
>               uvmexp.wired--;
>       }
> }
> 
> 

-- thorpej

Reply via email to