To investigate the race exposed by the last locking change in
uvm_map_inentry() [0], I'd like to add the following tracepoints.

The idea is to compare page fault addresses and permissions with
the insertion/removal of entries in a given map.  Diff below is
the first part of the puzzle, ok?

[0] https://marc.info/?l=openbsd-tech&m=157293690312531&w=2

An example of bt(5) script using those tracepoints look like this:

  tracepoint:uvm:fault {
  printf("%s:%d(%s) fault   0x%x type=0x%x, prot=0x%x\n",
      nsecs, tid, comm, arg0, arg1, arg2);
  }
  tracepoint:uvm:map_insert {
        printf("%s:%d(%s) insert [0x%x, 0x%x), prot=0x%x\n",
             nsecs, tid, comm, arg0, arg1, arg2);
  }
  tracepoint:uvm:map_remove {
        printf("%s:%d(%s) remove [0x%x, 0x%x) prot=0x%x\n",
             nsecs, tid, comm, arg0, arg1, arg2);
  }


Index: uvm/uvm_fault.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
retrieving revision 1.97
diff -u -p -r1.97 uvm_fault.c
--- uvm/uvm_fault.c     8 Dec 2019 12:37:45 -0000       1.97
+++ uvm/uvm_fault.c     11 Sep 2020 07:16:01 -0000
@@ -38,6 +38,7 @@
 #include <sys/proc.h>
 #include <sys/malloc.h>
 #include <sys/mman.h>
+#include <sys/tracepoint.h>
 
 #include <uvm/uvm.h>
 
@@ -507,6 +508,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
        pg = NULL;
 
        uvmexp.faults++;        /* XXX: locking? */
+       TRACEPOINT(uvm, fault, vaddr, fault_type, access_type, NULL);
 
        /* init the IN parameters in the ufi */
        ufi.orig_map = orig_map;
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_map.c,v
retrieving revision 1.265
diff -u -p -r1.265 uvm_map.c
--- uvm/uvm_map.c       6 Jul 2020 19:22:40 -0000       1.265
+++ uvm/uvm_map.c       11 Sep 2020 07:41:53 -0000
@@ -95,6 +95,7 @@
 #include <sys/signalvar.h>
 #include <sys/syslog.h>
 #include <sys/user.h>
+#include <sys/tracepoint.h>
 
 #ifdef SYSVSHM
 #include <sys/shm.h>
@@ -455,6 +456,9 @@ uvm_mapent_addr_insert(struct vm_map *ma
        KDASSERT((entry->start & (vaddr_t)PAGE_MASK) == 0 &&
            (entry->end & (vaddr_t)PAGE_MASK) == 0);
 
+       TRACEPOINT(uvm, map_insert,
+           entry->start, entry->end, entry->protection, NULL);
+
        UVM_MAP_REQ_WRITE(map);
        res = RBT_INSERT(uvm_map_addr, &map->addr, entry);
        if (res != NULL) {
@@ -474,6 +478,9 @@ void
 uvm_mapent_addr_remove(struct vm_map *map, struct vm_map_entry *entry)
 {
        struct vm_map_entry *res;
+
+       TRACEPOINT(uvm, map_remove,
+           entry->start, entry->end, entry->protection, NULL);
 
        UVM_MAP_REQ_WRITE(map);
        res = RBT_REMOVE(uvm_map_addr, &map->addr, entry);
Index: dev/dt/dt_prov_static.c
===================================================================
RCS file: /cvs/src/sys/dev/dt/dt_prov_static.c,v
retrieving revision 1.2
diff -u -p -r1.2 dt_prov_static.c
--- dev/dt/dt_prov_static.c     25 Mar 2020 14:59:23 -0000      1.2
+++ dev/dt/dt_prov_static.c     11 Sep 2020 07:43:58 -0000
@@ -34,7 +34,7 @@ struct dt_provider dt_prov_static = {
 };
 
 /*
- * Scheduler provider
+ * Scheduler
  */
 DT_STATIC_PROBE2(sched, dequeue, "pid_t", "pid_t");
 DT_STATIC_PROBE2(sched, enqueue, "pid_t", "pid_t");
@@ -51,6 +51,13 @@ DT_STATIC_PROBE1(raw_syscalls, sys_enter
 DT_STATIC_PROBE1(raw_syscalls, sys_exit, "register_t");
 
 /*
+ * UVM
+ */
+DT_STATIC_PROBE3(uvm, fault, "vaddr_t", "vm_fault_t", "vm_prot_t");
+DT_STATIC_PROBE3(uvm, map_insert, "vaddr_t", "vaddr_t", "vm_prot_t");
+DT_STATIC_PROBE3(uvm, map_remove, "vaddr_t", "vaddr_t", "vm_prot_t");
+
+/*
  * List of all static probes
  */
 struct dt_probe *dtps_static[] = {
@@ -65,6 +72,10 @@ struct dt_probe *dtps_static[] = {
        /* Raw syscalls */
        &_DT_STATIC_P(raw_syscalls, sys_enter),
        &_DT_STATIC_P(raw_syscalls, sys_exit),
+       /* UVM */
+       &_DT_STATIC_P(uvm, fault),
+       &_DT_STATIC_P(uvm, map_insert),
+       &_DT_STATIC_P(uvm, map_remove),
 };
 
 int

Reply via email to