Diff below introduces two dummy pagers for subsystem that manipulate UVM
objects that are 'special'.  Those pagers will be used to enforce checks
in functions that expect a lock to be held, like:

        KASSERT(obj == NULL || UVM_OBJ_IS_PMAP(obj) ||
            rw_write_held(obj->vmobjlock));

They are also used, in the diff below, to document which routines expect
such objects and a serialization offered by the KERNEL_LOCK().  More
examples can be seen in my WIP unlocking diff.

The idea is taken from NetBSD which also use such dummy pager for some
of their pmaps.  I don't believe there's a need to change anything with
these usages of the uvm_obj_* API for the moment but at the same time it
helps me to have such implicit documentation.

ok?

Index: arch/amd64/amd64/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/pmap.c,v
retrieving revision 1.145
diff -u -p -r1.145 pmap.c
--- arch/amd64/amd64/pmap.c     18 Jun 2021 06:17:28 -0000      1.145
+++ arch/amd64/amd64/pmap.c     2 Sep 2021 19:55:57 -0000
@@ -671,7 +671,7 @@ pmap_bootstrap(paddr_t first_avail, padd
 
        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: arch/hppa/hppa/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/pmap.c,v
retrieving revision 1.175
diff -u -p -r1.175 pmap.c
--- arch/hppa/hppa/pmap.c       16 Jun 2021 09:02:21 -0000      1.175
+++ arch/hppa/hppa/pmap.c       2 Sep 2021 19:54:23 -0000
@@ -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: arch/i386/i386/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.214
diff -u -p -r1.214 pmap.c
--- arch/i386/i386/pmap.c       16 Jun 2021 09:02:21 -0000      1.214
+++ arch/i386/i386/pmap.c       2 Sep 2021 19:55:57 -0000
@@ -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: uvm/uvm_object.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_object.c,v
retrieving revision 1.19
diff -u -p -r1.19 uvm_object.c
--- uvm/uvm_object.c    16 Jun 2021 09:02:21 -0000      1.19
+++ uvm/uvm_object.c    2 Sep 2021 20:00:03 -0000
@@ -41,6 +41,16 @@
 
 #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
 
@@ -159,6 +169,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);
        /*
Index: uvm/uvm_object.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_object.h,v
retrieving revision 1.26
diff -u -p -r1.26 uvm_object.h
--- uvm/uvm_object.h    16 Jun 2021 09:02:21 -0000      1.26
+++ uvm/uvm_object.h    2 Sep 2021 20:02:13 -0000
@@ -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 *);
@@ -91,6 +93,12 @@ RBT_PROTOTYPE(uvm_objtree, vm_page, objt
 
 #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 *);
Index: uvm/uvm_page.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_page.c,v
retrieving revision 1.157
diff -u -p -r1.157 uvm_page.c
--- uvm/uvm_page.c      21 Apr 2021 10:02:05 -0000      1.157
+++ uvm/uvm_page.c      2 Sep 2021 19:59:22 -0000
@@ -791,6 +791,8 @@ uvm_pagealloc_multi(struct uvm_object *o
        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 
        int              i, r;
        voff_t          offset;
 
+       KASSERT(UVM_OBJ_IS_BUFCACHE(obj));
+       KERNEL_ASSERT_LOCKED();
 
        TAILQ_INIT(&plist);
        if (size == 0)

Reply via email to