1 /* $OpenBSD: dt_prov_static.c,v 1.11 2021/11/24 09:47:49 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/systm.h> 21 #include <sys/param.h> 22 #include <sys/tracepoint.h> 23 24 #include <dev/dt/dtvar.h> 25 26 int dt_prov_static_alloc(struct dt_probe *, struct dt_softc *, 27 struct dt_pcb_list *, struct dtioc_req *); 28 int dt_prov_static_hook(struct dt_provider *, ...); 29 30 struct dt_provider dt_prov_static = { 31 .dtpv_name = "tracepoint", 32 .dtpv_alloc = dt_prov_static_alloc, 33 .dtpv_enter = dt_prov_static_hook, 34 .dtpv_dealloc = NULL, 35 }; 36 37 /* 38 * Scheduler 39 */ 40 DT_STATIC_PROBE2(sched, dequeue, "pid_t", "pid_t"); 41 DT_STATIC_PROBE2(sched, enqueue, "pid_t", "pid_t"); 42 DT_STATIC_PROBE2(sched, off__cpu, "pid_t", "pid_t"); 43 DT_STATIC_PROBE0(sched, on__cpu); 44 DT_STATIC_PROBE0(sched, remain__cpu); 45 DT_STATIC_PROBE0(sched, sleep); 46 DT_STATIC_PROBE0(sched, wakeup); 47 48 /* 49 * Raw syscalls 50 */ 51 DT_STATIC_PROBE1(raw_syscalls, sys_enter, "register_t"); 52 DT_STATIC_PROBE1(raw_syscalls, sys_exit, "register_t"); 53 54 /* 55 * UVM 56 */ 57 DT_STATIC_PROBE3(uvm, fault, "vaddr_t", "vm_fault_t", "vm_prot_t"); 58 DT_STATIC_PROBE3(uvm, map_insert, "vaddr_t", "vaddr_t", "vm_prot_t"); 59 DT_STATIC_PROBE3(uvm, map_remove, "vaddr_t", "vaddr_t", "vm_prot_t"); 60 DT_STATIC_PROBE4(uvm, malloc, "int", "void *", "size_t", "int"); 61 DT_STATIC_PROBE3(uvm, free, "int", "void *", "size_t"); 62 DT_STATIC_PROBE3(uvm, pool_get, "void *", "void *", "int"); 63 DT_STATIC_PROBE2(uvm, pool_put, "void *", "void *"); 64 65 /* 66 * VFS 67 */ 68 DT_STATIC_PROBE3(vfs, bufcache_rel, "long", "int", "int64_t"); 69 DT_STATIC_PROBE3(vfs, bufcache_take, "long", "int", "int64_t"); 70 DT_STATIC_PROBE4(vfs, cleaner, "long", "int", "long", "long"); 71 72 /* 73 * VMM 74 */ 75 DT_STATIC_PROBE2(vmm, guest_enter, "void *", "void *"); 76 DT_STATIC_PROBE3(vmm, guest_exit, "void *", "void *", "uint64_t"); 77 78 /* 79 * SMR 80 */ 81 DT_STATIC_PROBE3(smr, call, "void *", "void *", "int"); 82 DT_STATIC_PROBE2(smr, called, "void *", "void *"); 83 DT_STATIC_PROBE1(smr, barrier_enter, "int"); 84 DT_STATIC_PROBE1(smr, barrier_exit, "int"); 85 DT_STATIC_PROBE0(smr, wakeup); 86 DT_STATIC_PROBE2(smr, thread, "uint64_t", "uint64_t"); 87 88 89 /* 90 * List of all static probes 91 */ 92 struct dt_probe *dtps_static[] = { 93 /* Scheduler */ 94 &_DT_STATIC_P(sched, dequeue), 95 &_DT_STATIC_P(sched, enqueue), 96 &_DT_STATIC_P(sched, off__cpu), 97 &_DT_STATIC_P(sched, on__cpu), 98 &_DT_STATIC_P(sched, remain__cpu), 99 &_DT_STATIC_P(sched, sleep), 100 &_DT_STATIC_P(sched, wakeup), 101 /* Raw syscalls */ 102 &_DT_STATIC_P(raw_syscalls, sys_enter), 103 &_DT_STATIC_P(raw_syscalls, sys_exit), 104 /* UVM */ 105 &_DT_STATIC_P(uvm, fault), 106 &_DT_STATIC_P(uvm, map_insert), 107 &_DT_STATIC_P(uvm, map_remove), 108 &_DT_STATIC_P(uvm, malloc), 109 &_DT_STATIC_P(uvm, free), 110 &_DT_STATIC_P(uvm, pool_get), 111 &_DT_STATIC_P(uvm, pool_put), 112 /* VFS */ 113 &_DT_STATIC_P(vfs, bufcache_rel), 114 &_DT_STATIC_P(vfs, bufcache_take), 115 &_DT_STATIC_P(vfs, cleaner), 116 /* VMM */ 117 &_DT_STATIC_P(vmm, guest_enter), 118 &_DT_STATIC_P(vmm, guest_exit), 119 /* SMR */ 120 &_DT_STATIC_P(smr, call), 121 &_DT_STATIC_P(smr, called), 122 &_DT_STATIC_P(smr, barrier_enter), 123 &_DT_STATIC_P(smr, barrier_exit), 124 &_DT_STATIC_P(smr, wakeup), 125 &_DT_STATIC_P(smr, thread), 126 }; 127 128 int 129 dt_prov_static_init(void) 130 { 131 int i; 132 133 for (i = 0; i < nitems(dtps_static); i++) 134 dt_dev_register_probe(dtps_static[i]); 135 136 return i; 137 } 138 139 int 140 dt_prov_static_alloc(struct dt_probe *dtp, struct dt_softc *sc, 141 struct dt_pcb_list *plist, struct dtioc_req *dtrq) 142 { 143 struct dt_pcb *dp; 144 145 KASSERT(dtioc_req_isvalid(dtrq)); 146 KASSERT(TAILQ_EMPTY(plist)); 147 148 dp = dt_pcb_alloc(dtp, sc); 149 if (dp == NULL) 150 return ENOMEM; 151 152 dp->dp_filter = dtrq->dtrq_filter; 153 dp->dp_evtflags = dtrq->dtrq_evtflags; 154 TAILQ_INSERT_HEAD(plist, dp, dp_snext); 155 156 return 0; 157 } 158 159 int 160 dt_prov_static_hook(struct dt_provider *dtpv, ...) 161 { 162 struct dt_probe *dtp; 163 struct dt_pcb *dp; 164 uintptr_t args[5]; 165 va_list ap; 166 int i; 167 168 va_start(ap, dtpv); 169 dtp = va_arg(ap, struct dt_probe *); 170 for (i = 0; i < dtp->dtp_nargs; i++) { 171 args[i] = va_arg(ap, uintptr_t); 172 } 173 va_end(ap); 174 175 KASSERT(dtpv == dtp->dtp_prov); 176 177 smr_read_enter(); 178 SMR_SLIST_FOREACH(dp, &dtp->dtp_pcbs, dp_pnext) { 179 struct dt_evt *dtev; 180 181 dtev = dt_pcb_ring_get(dp, 0); 182 if (dtev == NULL) 183 continue; 184 185 dtev->dtev_args[0] = args[0]; 186 dtev->dtev_args[1] = args[1]; 187 dtev->dtev_args[2] = args[2]; 188 dtev->dtev_args[3] = args[3]; 189 dtev->dtev_args[4] = args[4]; 190 191 dt_pcb_ring_consume(dp, dtev); 192 } 193 smr_read_leave(); 194 return 1; 195 } 196