On 08/12/20(Tue) 22:55, Jonathan Matthew wrote:
> On Mon, Dec 07, 2020 at 03:15:50PM -0300, Martin Pieuchot wrote:
> > Getting a page from the fault handler might require poking at some
> > swap-related states.
> > 
> > These are not in the hot-path of the fault handler so for the moment
> > just assert that the KERNEL_LOCK() is held or grab it if the function
> > might be called from an future unlocked path.
> > 
> > ok?
> 
> Could you add 'K' to the list of locks in the comment above struct uvmexp too?

Updated diff below.

> I went looking for other uses of swpgonly and saw that it's used under
> uvm_map_teardown -> uvm_unmap_kill_entry -> uvm_km_pgremove,
> and uvm_map_teardown ensures that the kernel lock is not held.
> Not related to this diff exactly, but is this something we need to fix?

I suppose that the problem can only occur if a kernel thread is exiting
since this code is only executed for the kernel pmap.  Anyway I added an
assertion.

Index: uvm/uvm_km.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_km.c,v
retrieving revision 1.137
diff -u -p -r1.137 uvm_km.c
--- uvm/uvm_km.c        23 May 2020 06:15:09 -0000      1.137
+++ uvm/uvm_km.c        10 Dec 2020 13:33:49 -0000
@@ -243,6 +243,7 @@ uvm_km_pgremove(struct uvm_object *uobj,
        voff_t curoff;
        int slot;
 
+       KERNEL_ASSERT_LOCKED();
        KASSERT(uobj->pgops == &aobj_pager);
 
        for (curoff = start ; curoff < end ; curoff += PAGE_SIZE) {
Index: uvm/uvm_swap.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_swap.c,v
retrieving revision 1.147
diff -u -p -r1.147 uvm_swap.c
--- uvm/uvm_swap.c      29 Sep 2020 11:47:41 -0000      1.147
+++ uvm/uvm_swap.c      10 Dec 2020 13:30:30 -0000
@@ -1403,7 +1403,7 @@ uvm_swap_alloc(int *nslots, boolean_t le
        /*
         * lock data lock, convert slots into blocks, and enter loop
         */
-
+       KERNEL_ASSERT_LOCKED();
 ReTry: /* XXXMRG */
        LIST_FOREACH(spp, &swap_priority, spi_swappri) {
                TAILQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) {
@@ -1449,8 +1449,10 @@ uvm_swapisfull(void)
 {
        int result;
 
+       KERNEL_LOCK();
        KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
        result = (uvmexp.swpgonly == uvmexp.swpages);
+       KERNEL_UNLOCK();
 
        return result;
 }
@@ -1465,6 +1467,7 @@ uvm_swap_markbad(int startslot, int nslo
 {
        struct swapdev *sdp;
 
+       KERNEL_LOCK();
        sdp = swapdrum_getsdp(startslot);
        if (sdp != NULL) {
                /*
@@ -1475,6 +1478,7 @@ uvm_swap_markbad(int startslot, int nslo
                 */
                sdp->swd_npgbad += nslots;
        }
+       KERNEL_UNLOCK();
 }
 
 /*
@@ -1501,7 +1505,7 @@ uvm_swap_free(int startslot, int nslots)
         * in the extent, and return.   must hold pri lock to do
         * lookup and access the extent.
         */
-
+       KERNEL_LOCK();
        sdp = swapdrum_getsdp(startslot);
        KASSERT(uvmexp.nswapdev >= 1);
        KASSERT(sdp != NULL);
@@ -1533,6 +1537,7 @@ uvm_swap_free(int startslot, int nslots)
                }
        }
 #endif /* UVM_SWAP_ENCRYPT */
+       KERNEL_UNLOCK();
 }
 
 /*
@@ -1567,6 +1572,7 @@ uvm_swap_get(struct vm_page *page, int s
                return VM_PAGER_ERROR;
        }
 
+       KERNEL_LOCK();
        /* this page is (about to be) no longer only in swap. */
        uvmexp.swpgonly--;
 
@@ -1577,7 +1583,7 @@ uvm_swap_get(struct vm_page *page, int s
                /* oops, the read failed so it really is still only in swap. */
                uvmexp.swpgonly++;
        }
-
+       KERNEL_UNLOCK();
        return (result);
 }
 
@@ -1599,6 +1605,8 @@ uvm_swap_io(struct vm_page **pps, int st
        struct swapdev *sdp;
        int     encrypt = 0;
 #endif
+
+       KERNEL_ASSERT_LOCKED();
 
        write = (flags & B_READ) == 0;
        async = (flags & B_ASYNC) != 0;
Index: uvm/uvmexp.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvmexp.h,v
retrieving revision 1.6
diff -u -p -r1.6 uvmexp.h
--- uvm/uvmexp.h        1 Dec 2020 13:56:22 -0000       1.6
+++ uvm/uvmexp.h        10 Dec 2020 13:31:01 -0000
@@ -42,6 +42,7 @@
  *
  *  Locks used to protect struct members in this file:
  *     I       immutable after creation
+ *     K       kernel lock
  *     F       uvm_lock_fpageq
  */
 struct uvmexp {
@@ -79,9 +80,9 @@ struct uvmexp {
 
        /* swap */
        int nswapdev;   /* number of configured swap devices in system */
-       int swpages;    /* number of PAGE_SIZE'ed swap pages */
+       int swpages;    /* [K] number of PAGE_SIZE'ed swap pages */
        int swpginuse;  /* number of swap pages in use */
-       int swpgonly;   /* number of swap pages in use, not also in RAM */
+       int swpgonly;   /* [K] number of swap pages in use, not also in RAM */
        int nswget;     /* number of swap pages moved from disk to RAM */
        int nanon;      /* XXX number total of anon's in system */
        int unused05;   /* formerly nanonneeded */

Reply via email to