#include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h>
#include <sys/tracepoint.h>
#include <dev/dt/dtvar.h>
int dt_prov_static_alloc(struct dt_probe *, struct dt_softc *,
struct dt_pcb_list *, struct dtioc_req *);
int dt_prov_static_hook(struct dt_provider *, ...);
struct dt_provider dt_prov_static = {
.dtpv_name = "tracepoint",
.dtpv_alloc = dt_prov_static_alloc,
.dtpv_enter = dt_prov_static_hook,
.dtpv_dealloc = NULL,
};
DT_STATIC_PROBE2(sched, dequeue, "pid_t", "pid_t");
DT_STATIC_PROBE2(sched, enqueue, "pid_t", "pid_t");
DT_STATIC_PROBE3(sched, fork, "pid_t", "pid_t", "int");
DT_STATIC_PROBE2(sched, off__cpu, "pid_t", "pid_t");
DT_STATIC_PROBE0(sched, on__cpu);
DT_STATIC_PROBE0(sched, remain__cpu);
DT_STATIC_PROBE0(sched, sleep);
DT_STATIC_PROBE0(sched, stop);
DT_STATIC_PROBE3(sched, steal, "pid_t", "pid_t", "int");
DT_STATIC_PROBE2(sched, unsleep, "pid_t", "pid_t");
DT_STATIC_PROBE3(sched, wakeup, "pid_t", "pid_t", "int");
DT_STATIC_PROBE3(sched, unstop, "pid_t", "pid_t", "int");
DT_STATIC_PROBE1(raw_syscalls, sys_enter, "register_t");
DT_STATIC_PROBE1(raw_syscalls, sys_exit, "register_t");
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");
DT_STATIC_PROBE4(uvm, malloc, "int", "void *", "size_t", "int");
DT_STATIC_PROBE3(uvm, free, "int", "void *", "size_t");
DT_STATIC_PROBE3(uvm, pool_get, "void *", "void *", "int");
DT_STATIC_PROBE2(uvm, pool_put, "void *", "void *");
DT_STATIC_PROBE3(vfs, bufcache_rel, "long", "int", "int64_t");
DT_STATIC_PROBE3(vfs, bufcache_take, "long", "int", "int64_t");
DT_STATIC_PROBE4(vfs, cleaner, "long", "int", "long", "long");
#ifdef __amd64__
DT_STATIC_PROBE2(vmm, guest_enter, "void *", "void *");
DT_STATIC_PROBE3(vmm, guest_exit, "void *", "void *", "uint64_t");
DT_STATIC_PROBE4(vmm, inout, "void *", "uint16_t", "uint8_t", "uint32_t");
#endif
DT_STATIC_PROBE3(smr, call, "void *", "void *", "int");
DT_STATIC_PROBE2(smr, called, "void *", "void *");
DT_STATIC_PROBE1(smr, barrier_enter, "int");
DT_STATIC_PROBE1(smr, barrier_exit, "int");
DT_STATIC_PROBE0(smr, wakeup);
DT_STATIC_PROBE2(smr, thread, "uint64_t", "uint64_t");
DT_STATIC_PROBE0(refcnt, none);
DT_STATIC_PROBE3(refcnt, ethmulti, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, ifaddr, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, ifmaddr, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, inpcb, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, rtentry, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, socket, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, syncache, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, tdb, "void *", "int", "int");
DT_STATIC_PROBE0(rwlock, none);
DT_STATIC_PROBE3(rwlock, netlock, "void *", "int", "int");
DT_STATIC_PROBE3(rwlock, solock, "void *", "int", "int");
struct dt_probe *const dtps_static[] = {
&_DT_STATIC_P(sched, dequeue),
&_DT_STATIC_P(sched, enqueue),
&_DT_STATIC_P(sched, fork),
&_DT_STATIC_P(sched, off__cpu),
&_DT_STATIC_P(sched, on__cpu),
&_DT_STATIC_P(sched, remain__cpu),
&_DT_STATIC_P(sched, sleep),
&_DT_STATIC_P(sched, stop),
&_DT_STATIC_P(sched, steal),
&_DT_STATIC_P(sched, unsleep),
&_DT_STATIC_P(sched, wakeup),
&_DT_STATIC_P(sched, unstop),
&_DT_STATIC_P(raw_syscalls, sys_enter),
&_DT_STATIC_P(raw_syscalls, sys_exit),
&_DT_STATIC_P(uvm, fault),
&_DT_STATIC_P(uvm, map_insert),
&_DT_STATIC_P(uvm, map_remove),
&_DT_STATIC_P(uvm, malloc),
&_DT_STATIC_P(uvm, free),
&_DT_STATIC_P(uvm, pool_get),
&_DT_STATIC_P(uvm, pool_put),
&_DT_STATIC_P(vfs, bufcache_rel),
&_DT_STATIC_P(vfs, bufcache_take),
&_DT_STATIC_P(vfs, cleaner),
#ifdef __amd64__
&_DT_STATIC_P(vmm, guest_enter),
&_DT_STATIC_P(vmm, guest_exit),
&_DT_STATIC_P(vmm, inout),
#endif
&_DT_STATIC_P(smr, call),
&_DT_STATIC_P(smr, called),
&_DT_STATIC_P(smr, barrier_enter),
&_DT_STATIC_P(smr, barrier_exit),
&_DT_STATIC_P(smr, wakeup),
&_DT_STATIC_P(smr, thread),
&_DT_STATIC_P(refcnt, none),
&_DT_STATIC_P(refcnt, ethmulti),
&_DT_STATIC_P(refcnt, ifaddr),
&_DT_STATIC_P(refcnt, ifmaddr),
&_DT_STATIC_P(refcnt, inpcb),
&_DT_STATIC_P(refcnt, rtentry),
&_DT_STATIC_P(refcnt, socket),
&_DT_STATIC_P(refcnt, syncache),
&_DT_STATIC_P(refcnt, tdb),
&_DT_STATIC_P(rwlock, none),
&_DT_STATIC_P(rwlock, netlock),
&_DT_STATIC_P(rwlock, solock),
};
struct dt_probe *const *dtps_index_refcnt;
struct dt_probe *const *dtps_index_rwlock;
int
dt_prov_static_init(void)
{
int i;
for (i = 0; i < nitems(dtps_static); i++) {
if (dtps_static[i] == &_DT_STATIC_P(refcnt, none))
dtps_index_refcnt = &dtps_static[i];
if (dtps_static[i] == &_DT_STATIC_P(rwlock, none))
dtps_index_rwlock = &dtps_static[i];
dt_dev_register_probe(dtps_static[i]);
}
return i;
}
int
dt_prov_static_alloc(struct dt_probe *dtp, struct dt_softc *sc,
struct dt_pcb_list *plist, struct dtioc_req *dtrq)
{
struct dt_pcb *dp;
KASSERT(TAILQ_EMPTY(plist));
dp = dt_pcb_alloc(dtp, sc);
if (dp == NULL)
return ENOMEM;
dp->dp_evtflags = dtrq->dtrq_evtflags;
TAILQ_INSERT_HEAD(plist, dp, dp_snext);
return 0;
}
int
dt_prov_static_hook(struct dt_provider *dtpv, ...)
{
struct dt_probe *dtp;
struct dt_pcb *dp;
uintptr_t args[5];
va_list ap;
int i;
va_start(ap, dtpv);
dtp = va_arg(ap, struct dt_probe *);
for (i = 0; i < dtp->dtp_nargs; i++) {
args[i] = va_arg(ap, uintptr_t);
}
va_end(ap);
KASSERT(dtpv == dtp->dtp_prov);
smr_read_enter();
SMR_SLIST_FOREACH(dp, &dtp->dtp_pcbs, dp_pnext) {
struct dt_evt *dtev;
dtev = dt_pcb_ring_get(dp, 0);
if (dtev == NULL)
continue;
dtev->dtev_args[0] = args[0];
dtev->dtev_args[1] = args[1];
dtev->dtev_args[2] = args[2];
dtev->dtev_args[3] = args[3];
dtev->dtev_args[4] = args[4];
dt_pcb_ring_consume(dp, dtev);
}
smr_read_leave();
return 1;
}