2020å¹´ã¯è²ã ãã£ããã§ãããä¸ç²æãªããæ®ãã¾ããã2021å¹´ãé å¼µãã¾ãï¼1è¡ã§å»å¹´ã®ç·æ¬ã¨ä»å¹´ã®æ±è² ï¼ã
ã§ãRustã¨BPF CO-REã2ã¤ã®sotaï¼2020å¹´æ«ã«è¦ããè¨èã®ä¸ã¤ï¼ ãããã°ã«æ¸ãã¦æ°çãä¸ãã¦ããããã
ï¼ã¯ããã«: ååèªåã¡ã¢ã®ã¤ãããªãã§ãï¼ ã¨ããè¨ã訳ããã¦ããã¾ããèªèãç¨èªãªã©ééããããã°çªã£è¾¼ãã§...ï¼
BPF CO-REãã³ã¬ã£ã¦ãªãã§ãã
ä¸è¨è¨äºã«æ¸ãã¦ããéãï¼ããã«è¨ãã° Why We Switched from BCC to libbpf for Linux BPF Performance Analysis | PingCAP ã®éãï¼ãBCCã®ãããã¯ã·ã§ã³å©ç¨ã«ã¯ãã³ã³ãã¤ã©ãããããã¡ã¤ã«ãªã©ããããã®ä¾åãå®è¡æã«ã³ã³ãã¤ã«ããããã¨ã«ãããªã¼ãããããªã©å¤ãã®åé¡ããã£ãã*1ãããè¨ã£ãå®è¡æã«ã³ã³ãã¤ã«ããªãã¨ãããªãåé¡ããç°å¢ä¾åã大ããåé¡ã¯ BTF ã BPF CO-RE ã¨ãlibbpfçµç±ã§ã®å©ç¨ãªã©ã§è§£æ¶ããè¦è¾¼ã¿ãªã®ã§ãã£ã¡ãæã£ã¦è¡ã£ãã»ããããã¨ãã話ãããã
ã¼ããRubyçBCCãã¼ããéçºãã¦ããã®ã§ãBCCã®deprecatedåã«ã¯éºæ¾ã§ã¯ãããããããsotaã£ã¦ãã¨ãªãã§ãã...ã
ã§ãlibbpfã§ã®ãã¼ã«å®è£ ãµã³ãã«ã¯bccã®ãªãã¸ããªã«ããã§ã«ãããã馴æã¿ execsnoop ãªã©ãä¸éã移æ¤å®äºãã¦ãã模æ§ã
ã¯ããCãªãã§ããã¯ã³ãã¤ããª*2ã«ãããã®ã§ãããªã®ã§ããã...ã
è¤éãªãã¼ã«ããã¹ã¦Cã§ä½ããã¨ã¯ãåç´ãªã¡ã¢ãªãæååã®æ±ãä¸ã¤ã¨ã£ã¦ãé£ããå ´é¢ãå¤ããä¿å®æ§ãä¸ããã ããã
BPFããã°ã©ã é¨åã¯Cè¨èªã¨è¨ã£ã¦ãDSLã®ãããªãã®ã§ãè¤éãªãã¨ã¯ããªãã«ãã¦ããã§ããã°BPFãå©ç¨ããå´ã§ã¯ä»ã®è¨èªã®åãåãããã
libbpf-rs ã®å©ç¨
Rustã® libbpf_rs ã¯ã¬ã¼ããç¨ããã¨ãRustã§BPFãã¼ã«ãä½æã§ãããããããåºæ¬çã«CO-REãªãã¤ããªãä½ããã
ã¾ãã¯examplesã«ãããã¤ã«ã¤ãã¦ãç°å¢ãä½ã£ã¦è©¦ãã¦ã¿ãã
Ubuntu Groovyç°å¢ã®ç¨æ
æå¾
ã大ãããã¦ããã¦ãªãã ãã©ããããããç¾ç¶BTF + BPF CO-REãªãã¤ããªãåããã®ã¯å¤§å¤ã§ããã CONFIG_DEBUG_INFO_BTF
ãæå¹ã«ãªã£ãã«ã¼ãã«ãä½ãã®ãããããçµæ§å¤§å¤ã§ããããæå¹ã«ãªã£ãã«ã¼ãã«ã«ã¯ /sys/kernel/btf/vmlinux
ã¨ãããã¡ã¤ã«ãsysfsã«çãã¦ããã
$ ls -l /sys/kernel/btf/vmlinux -r--r--r-- 1 root root 3565534 Jan 5 09:28 /sys/kernel/btf/vmlinux
ããããUbuntuã§ããã¨Groovyï¼20.10ï¼ä»¥éã®æ¨æºLinuxã«ã¼ãã«ã§ã¯ããã©ã«ãã§æå¹ã«ãªã£ã¦ããããããªã使ãã¦ä¾¿å©ãªã®ã§ãä»åã¯ãã®ç°å¢ã使ããèªè
ã®çæ§ã¯Vagrantãªã©ã§é©å®è©¦ããããããªããGroovyã§ã¯ãCã®BPFããã°ã©ã ã®ãã«ãã§ä¾¿å©ãª libbpf-dev
ããããããã±ã¼ã¸ã«ãªã£ã¦ããã«å
¥ããããã
ã¨ãããã¨ã§Ubuntu Groovyã§å¿ è¦ãªããã±ã¼ã¸ãå ¥ãã¾ãã
$ sudo apt install libelf-dev libgcc-s1 clang libbpf-dev ## Rustãã»ããã¢ãããã¡ãã $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh $ . $HOME/.cargo/env
runqslower ãåããã¦ã¿ã
libbps_rs ããã§ãã¯ã¢ã¦ãã
$ git clone https://github.com/libbpf/libbpf-rs.git $ cd libbpf-rs/examples/runqslower
libbpf-cargo
ãå
¥ãã¦ãã¾ãã¯bpfããã°ã©ã ã®ã¿ããã«ããã¦ã¿ãã
$ cargo install libbpf-cargo $ cargo libbpf build
targeté
ä¸ã« runqslower.bpf.o
ãã³ã³ãã¤ã«ããã¦ããã
$ ls -l ../../target/bpf/ total 932 -rw-rw-r-- 1 vagrant vagrant 951944 Jan 6 09:49 runqslower.bpf.o
ã¾ããBPFããã°ã©ã ã«ã¢ã¯ã»ã¹ããã³ã¼ãã®skelãèªåçæãã¦ãããã
$ cargo libbpf gen Warning: unrecognized map: .maps Warning: unrecognized map: license $ ls -l src/bpf/ total 2692 -rw-rw-r-- 1 vagrant vagrant 192 Jan 6 09:50 mod.rs -rw-rw-r-- 1 vagrant vagrant 2281 Jan 6 09:48 runqslower.bpf.c -rw-rw-r-- 1 vagrant vagrant 234 Jan 6 09:48 runqslower.h -rw-rw-r-- 1 vagrant vagrant 6680 Jan 6 09:50 runqslower.skel.rs lrwxrwxrwx 1 vagrant vagrant 13 Jan 6 09:48 vmlinux.h -> vmlinux_505.h -rw-rw-r-- 1 vagrant vagrant 2734479 Jan 6 09:48 vmlinux_505.h
mod.rs
㨠runqslower.skel.rs
ãããã§ããã®ãã¡ã¤ã«ãå®ç¾©ããæ§é ä½ã«ãã©ã¡ã¼ã¿ã渡ãããã¼ããã¦ã¢ã¿ããããã以ä¸ã¯æç²ã
mod bpf; use bpf::*; let mut skel_builder = RunqslowerSkelBuilder::default(); let mut open_skel = skel_builder.open()?; open_skel.rodata().min_us = opts.latency; //... let mut skel = open_skel.load()?; skel.attach()?; let perf = PerfBufferBuilder::new(skel.maps().events()) .sample_cb(handle_event) .lost_cb(handle_lost_events) .build()?; loop { perf.poll(Duration::from_millis(100))?; }
skelãããã° cargo build
ã§ããã°ã©ã æ¬ä½ããã«ãã§ããã
$ ls -l ../../target/debug/ total 17856 drwxrwxr-x 28 vagrant vagrant 4096 Jan 6 09:53 build drwxrwxr-x 2 vagrant vagrant 20480 Jan 6 09:54 deps drwxrwxr-x 2 vagrant vagrant 4096 Jan 6 09:53 examples drwxrwxr-x 4 vagrant vagrant 4096 Jan 6 09:54 incremental -rwxrwxr-x 2 vagrant vagrant 18245232 Jan 6 09:54 runqslower -rw-rw-r-- 1 vagrant vagrant 773 Jan 6 09:54 runqslower.d
å®è¡ãå°ãè² è·ãããã¦ã¿ãã°è²ã åºã¦ãã¦ãã¡ããã¨é ãrun queueãæ¤ç¥ã§ãã¦ãããã
$ sudo ../../target/debug/runqslower Tracing run queue latency higher than 10000 us TIME COMM TID LAT(us) 09:55:13 kworker/11:0 38523 12390 09:56:42 http 71282 36409 09:57:05 kworker/6:1 48057 14452 09:58:59 dockerd 73130 34074 09:58:59 dockerd 73129 15471 09:58:59 dockerd 73131 48768 09:58:59 kworker/u30:2 71779 12502 09:58:59 containerd 71511 11318 09:58:59 dockerd 73251 88511 09:58:59 containerd-shim 76464 17829 09:58:59 containerd-shim 75362 17918 09:58:59 containerd-shim 79165 17978 09:58:59 sshd 2470 21413 09:58:59 ksoftirqd/9 66 38959 09:58:59 containerd-shim 77094 10517
ãã¤ããªã®ç´ æ§
ãã®ãã¤ããªã¯ããªã³ã¯ã¯ããããæãã§ã
$ ldd ../../target/debug/runqslower linux-vdso.so.1 (0x00007ffd75af9000) libelf.so.1 => /lib/x86_64-linux-gnu/libelf.so.1 (0x00007fb5944fe000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fb5944e1000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb5944c6000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb5944bb000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb594499000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb594493000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb5942a7000) /lib64/ld-linux-x86-64.so.2 (0x00007fb5948ac000)
èµ·åããéã«ã¯ã /sys/kernel/btf/vmlinux
ã®ã¿ãèªã¿åããã«ã¼ãã«ããããªã©ãæ¹ãã¦å©ç¨ãã¦ããªããã¨ãããããsysfsã®ãã¡ã¤ã«ã«ã ãä¾åãããããã³ã³ããã«ãã³ç½®ããã¦ãåãããã¨ã容æã§ãããã¨èãããã*3ã
$ sudo strace -y -e file ../../target/debug/runqslower execve("../../target/debug/runqslower", ["../../target/debug/runqslower"], 0x7ffe8c882688 /* 13 vars */) = 0 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libelf.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libelf-0.181.so> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libz.so.1.2.11> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libgcc_s.so.1> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/librt-2.32.so> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libpthread-2.32.so> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libdl-2.32.so> openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libc-2.32.so> openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3</proc/84098/maps> access("/sys/kernel/btf/vmlinux", R_OK) = 0 openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3</sys/kernel/btf/vmlinux> openat(AT_FDCWD, "/sys/devices/system/cpu/possible", O_RDONLY) = 5</sys/devices/system/cpu/possible> Tracing run queue latency higher than 10000 us TIME COMM TID LAT(us) openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY) = 14</sys/devices/system/cpu/online> openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 29</usr/share/zoneinfo/Etc/UTC> 10:01:53 systemd-journal 478 55310 ...
次ã¯ãCã®libbpf toolsãRustã«ç§»æ¤ãã¦ã¿ãããããã
追è¨: id:y_uuki ããã®è³ªåããææãè¸ã¾ãããã¤ã注éãã¤ãã¦ãã¾ã @ 2021/01/06 19:47
*1:å®éåããã®ã§ãã£ã¨ãã¨ããç°å¢ãå¤ãã£ãã®ã§ã¯ãªããã¨æè
*2:追è¨: ããã§ã¯ãã³ã³ãã¤ã«æ¸ã¿BPFããã°ã©ã ã¨å©ç¨å´ããã°ã©ã ãä¸ä½ã«ãªã£ã¦ããããããã®æå³ãéçãªã³ã¯ãªã©ã¯èæ ®ãã¾ãã
*3:追è¨: ãªãããã®è¾ºãã®ç¹å¾´ã¯Cå®è£ ã®libbpf-toolsãåæ§ã§ã¯ãããRustã§å©ç¨å´ããã°ã©ã ãå®è£ ããã¡ãªããã¨ãã¦ã¯ãRustèªä½ã®å®å ¨æ§ãçç£æ§ã大ããã¨æã