Tmp: FreeBSD DTrace 產生 Flame Graph
目錄
可以看到有 profile-97, profile-199 … profile-4999 還有 tick-1 … tick-5000,前者是 CPU sampling profiler(基於 interrupt / PMC / sampling),後者是 scheduler tick / timer interrupt sampling 適合 long-run performance trend。
kola@:~/proj/mac_casper/test/performance/syscall/sysctl $ sudo dtrace \
-x stackframes=100 \
-o stacks.out \
-c ./perf_baseline \
-n '
profile-4999
/pid == $target/
{
@[stack()] = count();
}'
kola@:~/proj/mac_casper/test/performance/syscall/sysctl $ perl ~/proj/FlameGraph/stackcollapse.pl stacks.out > folded.out
kola@:~/proj/mac_casper/test/performance/syscall/sysctl $ perl ~/proj/FlameGraph/flamegraph.pl \
--title="sysctl kernel stack with mac" \
folded.out > flame.svg實際例子
存成 SVG 後你就可以在瀏覽器打開,可以自由跟它互動像是看到全名等。
sysctl 函式
沒有 MAC 模組執行 sysctl
有 MAC 模組時執行 sysctl

總共 2495 samples 因為時間花的比較多,追蹤如下:
- Function: kernel`0xffffffff81050895 (333 samples, 13.35%)
- Function: kernel`0xffffffff810508ca (3 samples, 0.12%)
- Function: kernel`0xffffffff810508f9 (6 samples, 0.24%)
- Function: kernel`_rm_runlock (7 samples, 0.28%)
- Function: kernel`amd64_syscall (611 samples, 24.49%)
- Function: kernel`_rm_rlock (58 samples, 2.32%)
- Function: kernel`_rm_runlock (40 samples, 1.60%)
- Function: kernel`mac_error_select (4 samples, 0.16%)
- Function: kernel`mac_policy_sunlock_nosleep (9 samples, 0.36%)
- Function: kernel`mac_system_check_sysctl (19 samples, 0.76%)
- Function: kernel`prison_allow (7 samples, 0.28%)
- Function: kernel`prison_priv_check (2 samples, 0.08%)
- Function: kernel`sys___sysctl (434 samples, 17.39%)
- Function: kernel`_rm_rlock (82 samples, 3.29%)
- Function: kernel`_rm_runlock (51 samples, 2.04%)
- Function: kernel`mac_error_select (8 samples, 0.32%)
- Function: kernel`mac_label_get (1 samples, 0.04%)
- Function: kernel`mac_policy_slock_nosleep (2 samples, 0.08%)
- Function: kernel`mac_policy_sunlock_nosleep (1 samples, 0.04%)
- Function: kernel`strlen (3 samples, 0.12%)
- Function: kernel`sysctl_handle_string (35 samples, 1.40%)
- Function: kernel`sysctl_old_user (16 samples, 0.64%)
- Function: kernel`copyout_smap_erms (3 samples, 0.12%)
- Function: kernel`mac_label_get (1 samples, 0.04%)
- Function: kernel`strlen (33 samples, 1.32%)
- Function: kernel`sysctl_old_user (22 samples, 0.88%)
- Function: kernel`sysctl_root (172 samples, 6.89%)
- Function: mac_casper.ko`casper_mpo_system_check_sysctl_t (4 samples, 0.16%)
最前面的 unresolved kernel symbols (或者是 inlined / stripped functions),可以用 addr2line 來看一下:
kola@:~ $ for a in 0xffffffff81050895 0xffffffff810508ca 0xffffffff810508f9; do
addr2line -e /boot/kernel/kernel -f -C $a
done
fast_syscall_common
/usr/src/sys/amd64/amd64/exception.S:553
fast_syscall_common
/usr/src/sys/amd64/amd64/exception.S:561
fast_syscall_common
/usr/src/sys/amd64/amd64/exception.S:568
kola@:~ $ 這些是 FreeBSD 的 syscall entry path(快速 syscall 入口)。
然後再來使用 read-mostly lock,執行 amd64_syscall 這是 amd64 最上層 trap。
MAC 的
mac_error_select: 對很多 policy 做 select,只要有人 deny 就不過mac_policy_sunlock_nosleep: lock policy listmac_system_check_sysctl: 可不可以 do sysctlprison_allow: 看看 sysctl allowed inside jailprison_priv_check: privilege escalation check inside jailsys___sysctl: 開始做 sysctlsysctl_handle_string: 處理 string 類型sysctl_old_user: 把 kernel 資料複製到 user spacecopyout_smap_erms(真正寫到 user space)mac_label_get: 獲得 labelsysctl_root: 整個 sysctl dispatchercasper_mpo_system_check_sysctl_t: 我的 mac module
比較
MAC module 會做:
mac_error_select: 8 samplesmac_policy_sunlock_nosleep: 23 samplesmac_system_check_sysctl: 從 38 samples 變成了 88 samples_rm_rlock: 從 180 samples 變成 210 samples_rm_runlock: 從 13 samples 變成 204 samplesmac_error_select: 57 samplesmac_policy_slock_nosleep: 13 samplesmac_label_get: 8 samplesstrlen: 34 samples 變成 83 samples