While there are probes which can be used to track all on/off cpu activity, there are 2 problems with them:
- probing on everything is quite expensive
- there is no general way to distinguish blocking because of contention/waiting on something in kernel vs waiting on user (poll, select, waitpid etc.)
The patch below remedies the problem, although I don't have strong opinion on any names used.
The probes can be used with a script like this:
```#pragma D option dynvarsize=32m
/*
* The p_flag & 0x4 test filters out kernel threads.
*/
kernel:profile:*:sleep
/(curthread->td_proc->p_flag & 0x4) == 0/
{
self->ts = timestamp;
self->mesg = arg1;
}
kernel:profile:*:wakeup
/self->ts/
{
@[stack(30), stringof(self->mesg)] = sum(timestamp - self->ts);
self->ts = 0;
self->mesg = 0;
}
dtrace:::END
{
printa("%k\n%s\n%@d\n\n", @);
}
```
> # rm offcpu ; dtrace -s kprof-offcpu.d -o offcpu
> # cat offcpu | perl ~/FlameGraph/stackcollapse.pl | perl ~/FlameGraph/flamegraph.pl --color=io > /tmp/out-off.svg
https://people.freebsd.org/~mjg/fg/flix1-buildkernel-offcpu.svg