Getting started
ntprof is one binary with its eBPF programs inside. Build it once, copy it to the host and the target, and profile a workload that is already running. This page is the short version; the tutorial goes through it on two machines, one command at a time, with the output to expect.
Requirements
- To run: Linux 5.15 or 6.x with eBPF, root (or
CAP_BPFandCAP_PERFMON), the NVMe-oF modules loaded (on the host: connected withnvme connect), and BTF:/sys/kernel/btf/vmlinuxand the modules' own BTF. Modules built out of tree, such as MLNX OFED's DKMS packages, often lack it; see Kernels without BTF. - To build: clang 12 or later, bpftool, and the libelf and zlib development files. libbpf comes with the repository as a submodule.
Ubuntu's /usr/sbin/bpftool refuses to run on a kernel it has no package for; use
/usr/lib/linux-tools/<any version>/bpftool. The bpftool of Ubuntu 22.04 (v5.15) is too old ("Error finalizing
.BTF"): build v7.4.0 or later from libbpf/bpftool and pass
make BPFTOOL=/path/to/bpftool.
Build
git clone --recurse-submodules https://github.com/netlab-wisconsin/ntprof.git
cd ntprof
make # builds ./ntprof
make test # unit tests (no root, no BPF)
sudo make install # /usr/local/sbin/ntprof (PREFIX=, DESTDIR= as usual)
ntprof --version
At run time the binary needs only libelf and zlib, so a build from one machine runs on another with the same libraries.
Check the kernel
ntprof probe lists every hook for the role and transport you name, whether this kernel has it, and loads the
programs without attaching them:
sudo ntprof probe -r both -t tcp # host and target, NVMe/TCP
sudo ntprof probe -r host -t rdma # the host, NVMe/RDMA
Each object line says whether its module has BTF and which hook flavour it will use (fentry/fexit, or kprobes),
and the last line says load: ok. A hook the kernel's build has inlined shows as --; where ntprof has a stand-in
for it, the line says so.
Try it on one machine
With the stock nvme-tcp, nvmet-tcp and null_blk modules, fio and nvme-cli, the demo needs no SSD and no NIC:
tests/demo.sh # about two minutes; tests/demo.sh down removes the test bed
It exports a null_blk device through the kernel target on 127.0.0.1, connects to it, and shows a live breakdown, the two sides recorded separately and joined, and the latency amplification between queue depth 1 and 32.
Profile two machines
On the target, start recording first and stop last; on the host, record while the workload runs. Use the
same sampling rate (-s) on both: both sides then pick the same commands.
# target
sudo ntprof record -r target -t rdma -o target.ntp
# host
sudo ntprof record -t rdma -o host.ntp -d 30
# anywhere, with both files
ntprof report host.ntp target.ntp
ntprof record alone, on the host, reports the network and the target together, as one row ("network and target
(not recorded)"). -r both profiles a host and a target on the same machine in one command.
ntprof records one command in 1000 by default. At low rates (queue depth 1 does about 10,000 I/Os per second)
that leaves a few hundred commands a minute; use -s 100 for a short run. Every command passes the hooks either
way, so the overhead depends little on the rate.
Next
- Tutorial: every step on two machines, Linux and SPDK, with our output.
- Recording: roles, transports, filters, files.
- Reading a report and comparing two runs.