Introduce dummy pagers for 'special' subsystems using UVM objects.
authormpi <mpi@openbsd.org>
Sun, 5 Sep 2021 11:44:46 +0000 (11:44 +0000)
committermpi <mpi@openbsd.org>
Sun, 5 Sep 2021 11:44:46 +0000 (11:44 +0000)
Some pmaps (x86, hppa) and the buffer cache rely on UVM objects to allocate
and manipulate pages.  These objects should not be manipulated by uvm_fault()
and do not currently require the same locking enforcement.

Use the dummy pagers to explicitly document which UVM functions are meant to
manipulate UVM objects (uobj) that do not need the upcoming `vmobjlock' and
instead still rely on the KERNEL_LOCK().

Tested by many as part of a larger diff.

ok kettenis@, beck@

sys/arch/amd64/amd64/pmap.c
sys/arch/hppa/hppa/pmap.c
sys/arch/i386/i386/pmap.c
sys/kern/vfs_bio.c
sys/kern/vfs_biomem.c
sys/uvm/uvm_object.c
sys/uvm/uvm_object.h
sys/uvm/uvm_page.c

index 6ad63ff..4718576 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.145 2021/06/18 06:17:28 guenther Exp $     */
+/*     $OpenBSD: pmap.c,v 1.146 2021/09/05 11:44:46 mpi Exp $  */
 /*     $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
 
 /*
@@ -671,7 +671,7 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa)
 
        kpm = pmap_kernel();
        for (i = 0; i < PTP_LEVELS - 1; i++) {
-               uvm_obj_init(&kpm->pm_obj[i], NULL, 1);
+               uvm_obj_init(&kpm->pm_obj[i], &pmap_pager, 1);
                kpm->pm_ptphint[i] = NULL;
        }
        memset(&kpm->pm_list, 0, sizeof(kpm->pm_list));  /* pm_list not used */
@@ -1307,7 +1307,7 @@ pmap_create(void)
 
        /* init uvm_object */
        for (i = 0; i < PTP_LEVELS - 1; i++) {
-               uvm_obj_init(&pmap->pm_obj[i], NULL, 1);
+               uvm_obj_init(&pmap->pm_obj[i], &pmap_pager, 1);
                pmap->pm_ptphint[i] = NULL;
        }
        pmap->pm_stats.wired_count = 0;
index 1f95090..52f2c73 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.175 2021/06/16 09:02:21 mpi Exp $  */
+/*     $OpenBSD: pmap.c,v 1.176 2021/09/05 11:44:46 mpi Exp $  */
 
 /*
  * Copyright (c) 1998-2004 Michael Shalayeff
@@ -496,7 +496,7 @@ pmap_bootstrap(vaddr_t vstart)
         */
        kpm = &kernel_pmap_store;
        bzero(kpm, sizeof(*kpm));
-       uvm_obj_init(&kpm->pm_obj, NULL, 1);
+       uvm_obj_init(&kpm->pm_obj, &pmap_pager, 1);
        kpm->pm_space = HPPA_SID_KERNEL;
        kpm->pm_pid = HPPA_PID_KERNEL;
        kpm->pm_pdir_pg = NULL;
@@ -678,7 +678,7 @@ pmap_create(void)
 
        mtx_init(&pmap->pm_mtx, IPL_VM);
 
-       uvm_obj_init(&pmap->pm_obj, NULL, 1);
+       uvm_obj_init(&pmap->pm_obj, &pmap_pager, 1);
 
        for (space = 1 + arc4random_uniform(hppa_sid_max);
            pmap_sdir_get(space); space = (space + 1) % hppa_sid_max);
index a11178c..b5521e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.214 2021/06/16 09:02:21 mpi Exp $  */
+/*     $OpenBSD: pmap.c,v 1.215 2021/09/05 11:44:46 mpi Exp $  */
 /*     $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $        */
 
 /*
@@ -963,7 +963,7 @@ pmap_bootstrap(vaddr_t kva_start)
        kpm = pmap_kernel();
        mtx_init(&kpm->pm_mtx, -1); /* must not be used */
        mtx_init(&kpm->pm_apte_mtx, IPL_VM);
-       uvm_obj_init(&kpm->pm_obj, NULL, 1);
+       uvm_obj_init(&kpm->pm_obj, &pmap_pager, 1);
        bzero(&kpm->pm_list, sizeof(kpm->pm_list));  /* pm_list not used */
        kpm->pm_pdir = (vaddr_t)(proc0.p_addr->u_pcb.pcb_cr3 + KERNBASE);
        kpm->pm_pdirpa = proc0.p_addr->u_pcb.pcb_cr3;
@@ -1348,7 +1348,7 @@ pmap_create(void)
        mtx_init(&pmap->pm_apte_mtx, IPL_VM);
 
        /* init uvm_object */
-       uvm_obj_init(&pmap->pm_obj, NULL, 1);
+       uvm_obj_init(&pmap->pm_obj, &pmap_pager, 1);
        pmap->pm_stats.wired_count = 0;
        pmap->pm_stats.resident_count = 1;      /* count the PDP allocd below */
        pmap->pm_ptphint = NULL;
index b3472e9..843d2e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_bio.c,v 1.206 2021/06/16 09:02:21 mpi Exp $       */
+/*     $OpenBSD: vfs_bio.c,v 1.207 2021/09/05 11:44:46 mpi Exp $       */
 /*     $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $  */
 
 /*
@@ -560,7 +560,7 @@ bread_cluster_callback(struct buf *bp)
                struct uvm_object *oldobj = &bp->b_uobj;
                int page;
 
-               uvm_obj_init(newobj, NULL, 1);
+               uvm_obj_init(newobj, &bufcache_pager, 1);
                for (page = 0; page < atop(xbpp[i]->b_bufsize); page++) {
                        struct vm_page *pg = uvm_pagelookup(oldobj,
                            xbpp[i]->b_poffs + ptoa(page));
index 66dc482..b3c41c6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_biomem.c,v 1.49 2021/06/16 09:02:21 mpi Exp $ */
+/*     $OpenBSD: vfs_biomem.c,v 1.50 2021/09/05 11:44:46 mpi Exp $ */
 
 /*
  * Copyright (c) 2007 Artur Grabowski <art@openbsd.org>
@@ -259,7 +259,7 @@ buf_alloc_pages(struct buf *bp, vsize_t size)
        KASSERT(bp->b_data == NULL);
        splassert(IPL_BIO);
 
-       uvm_obj_init(&bp->b_uobj, NULL, 1);
+       uvm_obj_init(&bp->b_uobj, &bufcache_pager, 1);
 
        /*
         * Attempt to allocate with NOWAIT. if we can't, then throw
index e0aaf2e..872acb9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_object.c,v 1.19 2021/06/16 09:02:21 mpi Exp $     */
+/*     $OpenBSD: uvm_object.c,v 1.20 2021/09/05 11:44:46 mpi Exp $     */
 
 /*
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
 
 #include <uvm/uvm.h>
 
+/* Dummy object used by some pmaps for sanity checks. */
+const struct uvm_pagerops pmap_pager = {
+       /* nothing */
+};
+
+/* Dummy object used by the buffer cache for sanity checks. */
+const struct uvm_pagerops bufcache_pager = {
+       /* nothing */
+};
+
 /* We will fetch this page count per step */
 #define        FETCH_PAGECOUNT 16
 
@@ -160,6 +170,9 @@ uvm_obj_free(struct uvm_object *uobj)
        struct vm_page *pg;
        struct pglist pgl;
 
+       KASSERT(UVM_OBJ_IS_BUFCACHE(uobj));
+       KERNEL_ASSERT_LOCKED();
+
        TAILQ_INIT(&pgl);
        /*
         * Extract from rb tree in offset order. The phys addresses
index ebd89cb..9d32d20 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_object.h,v 1.26 2021/06/16 09:02:21 mpi Exp $     */
+/*     $OpenBSD: uvm_object.h,v 1.27 2021/09/05 11:44:46 mpi Exp $     */
 /*     $NetBSD: uvm_object.h,v 1.11 2001/03/09 01:02:12 chs Exp $      */
 
 /*
@@ -74,6 +74,8 @@ struct uvm_object {
 
 extern const struct uvm_pagerops uvm_vnodeops;
 extern const struct uvm_pagerops uvm_deviceops;
+extern const struct uvm_pagerops pmap_pager;
+extern const struct uvm_pagerops bufcache_pager;
 
 /* For object trees */
 int    uvm_pagecmp(const struct vm_page *, const struct vm_page *);
@@ -92,6 +94,12 @@ RBT_PROTOTYPE(uvm_objtree, vm_page, objt, uvm_pagecmp)
 #define        UVM_OBJ_IS_AOBJ(uobj)                                           \
        ((uobj)->pgops == &aobj_pager)
 
+#define UVM_OBJ_IS_PMAP(uobj)                                          \
+       ((uobj)->pgops == &pmap_pager)
+
+#define UVM_OBJ_IS_BUFCACHE(uobj)                                      \
+       ((uobj)->pgops == &bufcache_pager)
+
 void   uvm_obj_init(struct uvm_object *, const struct uvm_pagerops *, int);
 int    uvm_obj_wire(struct uvm_object *, voff_t, voff_t, struct pglist *);
 void   uvm_obj_unwire(struct uvm_object *, voff_t, voff_t);
index 8307b76..ee40e95 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_page.c,v 1.157 2021/04/21 10:02:05 mpi Exp $      */
+/*     $OpenBSD: uvm_page.c,v 1.158 2021/09/05 11:44:46 mpi Exp $      */
 /*     $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $        */
 
 /*
@@ -791,6 +791,8 @@ uvm_pagealloc_multi(struct uvm_object *obj, voff_t off, vsize_t size,
        struct vm_page  *pg;
        int              i, r;
 
+       KASSERT(UVM_OBJ_IS_BUFCACHE(obj));
+       KERNEL_ASSERT_LOCKED();
 
        TAILQ_INIT(&plist);
        r = uvm_pglistalloc(size, dma_constraint.ucr_low,
@@ -823,6 +825,8 @@ uvm_pagerealloc_multi(struct uvm_object *obj, voff_t off, vsize_t size,
        int              i, r;
        voff_t          offset;
 
+       KASSERT(UVM_OBJ_IS_BUFCACHE(obj));
+       KERNEL_ASSERT_LOCKED();
 
        TAILQ_INIT(&plist);
        if (size == 0)