Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm Avoid a panic from the sequence



details:   https://anonhg.NetBSD.org/src/rev/44e3696dcb03
branches:  trunk
changeset: 449645:44e3696dcb03
user:      kre <kre%NetBSD.org@localhost>
date:      Thu Mar 14 19:10:04 2019 +0000

description:
Avoid a panic from the sequence

        mlock(buf, 0);
        munlock(buf, 0);
        mlock(buf, page);
        munlock(buf, page);

where buf is page aligned, and page is actually anything > 0
(but not too big) which will get rounded up to the next multiple
of the page size.

In that sequence, it is possible that the 1st munlock() is optional.

Add a KASSERT() (or two) to detect the first effects of the problem
(without that, or in !DIAGNOSTIC kernels) the problem eventually
causes some kind of problem or other (most often still a panic.)

After this, mlock(anything, 0) (or munlock) validates "anything"
but is otherwise a no-op (regardless of the alignment of anything).

Also, don't treat mlock(buf, verybig) as equivalent to mlock(buf, 0)
which is (more or less) what we had been doing.

XXX pullup -8 (maybe -7 as well, need to check).

diffstat:

 sys/uvm/uvm_map.c  |  12 ++++++++++--
 sys/uvm/uvm_mmap.c |  20 ++++++++++++++------
 sys/uvm/uvm_page.c |   6 ++++--
 3 files changed, 28 insertions(+), 10 deletions(-)

diffs (111 lines):

diff -r 586a4184580a -r 44e3696dcb03 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Thu Mar 14 18:59:37 2019 +0000
+++ b/sys/uvm/uvm_map.c Thu Mar 14 19:10:04 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.358 2019/03/03 17:37:36 maxv Exp $       */
+/*     $NetBSD: uvm_map.c,v 1.359 2019/03/14 19:10:04 kre Exp $        */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.358 2019/03/03 17:37:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.359 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pax.h"
@@ -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.
         */
diff -r 586a4184580a -r 44e3696dcb03 sys/uvm/uvm_mmap.c
--- a/sys/uvm/uvm_mmap.c        Thu Mar 14 18:59:37 2019 +0000
+++ b/sys/uvm/uvm_mmap.c        Thu Mar 14 19:10:04 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_mmap.c,v 1.169 2017/12/19 18:34:47 kamil Exp $     */
+/*     $NetBSD: uvm_mmap.c,v 1.170 2019/03/14 19:10:04 kre Exp $       */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.169 2017/12/19 18:34:47 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.170 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_pax.h"
@@ -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)
diff -r 586a4184580a -r 44e3696dcb03 sys/uvm/uvm_page.c
--- a/sys/uvm/uvm_page.c        Thu Mar 14 18:59:37 2019 +0000
+++ b/sys/uvm/uvm_page.c        Thu Mar 14 19:10:04 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_page.c,v 1.198 2018/05/19 15:03:26 jdolecek Exp $  */
+/*     $NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $       */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.198 2018/05/19 15:03:26 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvm.h"
@@ -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--;
        }
 }



Home | Main Index | Thread Index | Old Index