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