bpf_iterators.rst 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. =============
  2. BPF Iterators
  3. =============
  4. ----------
  5. Motivation
  6. ----------
  7. There are a few existing ways to dump kernel data into user space. The most
  8. popular one is the ``/proc`` system. For example, ``cat /proc/net/tcp6`` dumps
  9. all tcp6 sockets in the system, and ``cat /proc/net/netlink`` dumps all netlink
  10. sockets in the system. However, their output format tends to be fixed, and if
  11. users want more information about these sockets, they have to patch the kernel,
  12. which often takes time to publish upstream and release. The same is true for popular
  13. tools like `ss <https://man7.org/linux/man-pages/man8/ss.8.html>`_ where any
  14. additional information needs a kernel patch.
  15. To solve this problem, the `drgn
  16. <https://www.kernel.org/doc/html/latest/bpf/drgn.html>`_ tool is often used to
  17. dig out the kernel data with no kernel change. However, the main drawback for
  18. drgn is performance, as it cannot do pointer tracing inside the kernel. In
  19. addition, drgn cannot validate a pointer value and may read invalid data if the
  20. pointer becomes invalid inside the kernel.
  21. The BPF iterator solves the above problem by providing flexibility on what data
  22. (e.g., tasks, bpf_maps, etc.) to collect by calling BPF programs for each kernel
  23. data object.
  24. ----------------------
  25. How BPF Iterators Work
  26. ----------------------
  27. A BPF iterator is a type of BPF program that allows users to iterate over
  28. specific types of kernel objects. Unlike traditional BPF tracing programs that
  29. allow users to define callbacks that are invoked at particular points of
  30. execution in the kernel, BPF iterators allow users to define callbacks that
  31. should be executed for every entry in a variety of kernel data structures.
  32. For example, users can define a BPF iterator that iterates over every task on
  33. the system and dumps the total amount of CPU runtime currently used by each of
  34. them. Another BPF task iterator may instead dump the cgroup information for each
  35. task. Such flexibility is the core value of BPF iterators.
  36. A BPF program is always loaded into the kernel at the behest of a user space
  37. process. A user space process loads a BPF program by opening and initializing
  38. the program skeleton as required and then invoking a syscall to have the BPF
  39. program verified and loaded by the kernel.
  40. In traditional tracing programs, a program is activated by having user space
  41. obtain a ``bpf_link`` to the program with ``bpf_program__attach()``. Once
  42. activated, the program callback will be invoked whenever the tracepoint is
  43. triggered in the main kernel. For BPF iterator programs, a ``bpf_link`` to the
  44. program is obtained using ``bpf_link_create()``, and the program callback is
  45. invoked by issuing system calls from user space.
  46. Next, let us see how you can use the iterators to iterate on kernel objects and
  47. read data.
  48. ------------------------
  49. How to Use BPF iterators
  50. ------------------------
  51. BPF selftests are a great resource to illustrate how to use the iterators. In
  52. this section, we’ll walk through a BPF selftest which shows how to load and use
  53. a BPF iterator program. To begin, we’ll look at `bpf_iter.c
  54. <https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/prog_tests/bpf_iter.c>`_,
  55. which illustrates how to load and trigger BPF iterators on the user space side.
  56. Later, we’ll look at a BPF program that runs in kernel space.
  57. Loading a BPF iterator in the kernel from user space typically involves the
  58. following steps:
  59. * The BPF program is loaded into the kernel through ``libbpf``. Once the kernel
  60. has verified and loaded the program, it returns a file descriptor (fd) to user
  61. space.
  62. * Obtain a ``link_fd`` to the BPF program by calling the ``bpf_link_create()``
  63. specified with the BPF program file descriptor received from the kernel.
  64. * Next, obtain a BPF iterator file descriptor (``bpf_iter_fd``) by calling the
  65. ``bpf_iter_create()`` specified with the ``bpf_link`` received from Step 2.
  66. * Trigger the iteration by calling ``read(bpf_iter_fd)`` until no data is
  67. available.
  68. * Close the iterator fd using ``close(bpf_iter_fd)``.
  69. * If needed to reread the data, get a new ``bpf_iter_fd`` and do the read again.
  70. The following are a few examples of selftest BPF iterator programs:
  71. * `bpf_iter_tcp4.c <https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c>`_
  72. * `bpf_iter_task_vma.c <https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/progs/bpf_iter_task_vma.c>`_
  73. * `bpf_iter_task_file.c <https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/progs/bpf_iter_task_file.c>`_
  74. Let us look at ``bpf_iter_task_file.c``, which runs in kernel space:
  75. Here is the definition of ``bpf_iter__task_file`` in `vmlinux.h
  76. <https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html#btf>`_.
  77. Any struct name in ``vmlinux.h`` in the format ``bpf_iter__<iter_name>``
  78. represents a BPF iterator. The suffix ``<iter_name>`` represents the type of
  79. iterator.
  80. ::
  81. struct bpf_iter__task_file {
  82. union {
  83. struct bpf_iter_meta *meta;
  84. };
  85. union {
  86. struct task_struct *task;
  87. };
  88. u32 fd;
  89. union {
  90. struct file *file;
  91. };
  92. };
  93. In the above code, the field 'meta' contains the metadata, which is the same for
  94. all BPF iterator programs. The rest of the fields are specific to different
  95. iterators. For example, for task_file iterators, the kernel layer provides the
  96. 'task', 'fd' and 'file' field values. The 'task' and 'file' are `reference
  97. counted
  98. <https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#file-descriptors-and-reference-counters>`_,
  99. so they won't go away when the BPF program runs.
  100. Here is a snippet from the ``bpf_iter_task_file.c`` file:
  101. ::
  102. SEC("iter/task_file")
  103. int dump_task_file(struct bpf_iter__task_file *ctx)
  104. {
  105. struct seq_file *seq = ctx->meta->seq;
  106. struct task_struct *task = ctx->task;
  107. struct file *file = ctx->file;
  108. __u32 fd = ctx->fd;
  109. if (task == NULL || file == NULL)
  110. return 0;
  111. if (ctx->meta->seq_num == 0) {
  112. count = 0;
  113. BPF_SEQ_PRINTF(seq, " tgid gid fd file\n");
  114. }
  115. if (tgid == task->tgid && task->tgid != task->pid)
  116. count++;
  117. if (last_tgid != task->tgid) {
  118. last_tgid = task->tgid;
  119. unique_tgid_count++;
  120. }
  121. BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd,
  122. (long)file->f_op);
  123. return 0;
  124. }
  125. In the above example, the section name ``SEC(iter/task_file)``, indicates that
  126. the program is a BPF iterator program to iterate all files from all tasks. The
  127. context of the program is ``bpf_iter__task_file`` struct.
  128. The user space program invokes the BPF iterator program running in the kernel
  129. by issuing a ``read()`` syscall. Once invoked, the BPF
  130. program can export data to user space using a variety of BPF helper functions.
  131. You can use either ``bpf_seq_printf()`` (and BPF_SEQ_PRINTF helper macro) or
  132. ``bpf_seq_write()`` function based on whether you need formatted output or just
  133. binary data, respectively. For binary-encoded data, the user space applications
  134. can process the data from ``bpf_seq_write()`` as needed. For the formatted data,
  135. you can use ``cat <path>`` to print the results similar to ``cat
  136. /proc/net/netlink`` after pinning the BPF iterator to the bpffs mount. Later,
  137. use ``rm -f <path>`` to remove the pinned iterator.
  138. For example, you can use the following command to create a BPF iterator from the
  139. ``bpf_iter_ipv6_route.o`` object file and pin it to the ``/sys/fs/bpf/my_route``
  140. path:
  141. ::
  142. $ bpftool iter pin ./bpf_iter_ipv6_route.o /sys/fs/bpf/my_route
  143. And then print out the results using the following command:
  144. ::
  145. $ cat /sys/fs/bpf/my_route
  146. -------------------------------------------------------
  147. Implement Kernel Support for BPF Iterator Program Types
  148. -------------------------------------------------------
  149. To implement a BPF iterator in the kernel, the developer must make a one-time
  150. change to the following key data structure defined in the `bpf.h
  151. <https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/include/linux/bpf.h>`_
  152. file.
  153. ::
  154. struct bpf_iter_reg {
  155. const char *target;
  156. bpf_iter_attach_target_t attach_target;
  157. bpf_iter_detach_target_t detach_target;
  158. bpf_iter_show_fdinfo_t show_fdinfo;
  159. bpf_iter_fill_link_info_t fill_link_info;
  160. bpf_iter_get_func_proto_t get_func_proto;
  161. u32 ctx_arg_info_size;
  162. u32 feature;
  163. struct bpf_ctx_arg_aux ctx_arg_info[BPF_ITER_CTX_ARG_MAX];
  164. const struct bpf_iter_seq_info *seq_info;
  165. };
  166. After filling the data structure fields, call ``bpf_iter_reg_target()`` to
  167. register the iterator to the main BPF iterator subsystem.
  168. The following is the breakdown for each field in struct ``bpf_iter_reg``.
  169. .. list-table::
  170. :widths: 25 50
  171. :header-rows: 1
  172. * - Fields
  173. - Description
  174. * - target
  175. - Specifies the name of the BPF iterator. For example: ``bpf_map``,
  176. ``bpf_map_elem``. The name should be different from other ``bpf_iter`` target names in the kernel.
  177. * - attach_target and detach_target
  178. - Allows for target specific ``link_create`` action since some targets
  179. may need special processing. Called during the user space link_create stage.
  180. * - show_fdinfo and fill_link_info
  181. - Called to fill target specific information when user tries to get link
  182. info associated with the iterator.
  183. * - get_func_proto
  184. - Permits a BPF iterator to access BPF helpers specific to the iterator.
  185. * - ctx_arg_info_size and ctx_arg_info
  186. - Specifies the verifier states for BPF program arguments associated with
  187. the bpf iterator.
  188. * - feature
  189. - Specifies certain action requests in the kernel BPF iterator
  190. infrastructure. Currently, only BPF_ITER_RESCHED is supported. This means
  191. that the kernel function cond_resched() is called to avoid other kernel
  192. subsystem (e.g., rcu) misbehaving.
  193. * - seq_info
  194. - Specifies the set of seq operations for the BPF iterator and helpers to
  195. initialize/free the private data for the corresponding ``seq_file``.
  196. `Click here
  197. <https://lore.kernel.org/bpf/20210212183107.50963-2-songliubraving@fb.com/>`_
  198. to see an implementation of the ``task_vma`` BPF iterator in the kernel.
  199. ---------------------------------
  200. Parameterizing BPF Task Iterators
  201. ---------------------------------
  202. By default, BPF iterators walk through all the objects of the specified types
  203. (processes, cgroups, maps, etc.) across the entire system to read relevant
  204. kernel data. But often, there are cases where we only care about a much smaller
  205. subset of iterable kernel objects, such as only iterating tasks within a
  206. specific process. Therefore, BPF iterator programs support filtering out objects
  207. from iteration by allowing user space to configure the iterator program when it
  208. is attached.
  209. --------------------------
  210. BPF Task Iterator Program
  211. --------------------------
  212. The following code is a BPF iterator program to print files and task information
  213. through the ``seq_file`` of the iterator. It is a standard BPF iterator program
  214. that visits every file of an iterator. We will use this BPF program in our
  215. example later.
  216. ::
  217. #include <vmlinux.h>
  218. #include <bpf/bpf_helpers.h>
  219. char _license[] SEC("license") = "GPL";
  220. SEC("iter/task_file")
  221. int dump_task_file(struct bpf_iter__task_file *ctx)
  222. {
  223. struct seq_file *seq = ctx->meta->seq;
  224. struct task_struct *task = ctx->task;
  225. struct file *file = ctx->file;
  226. __u32 fd = ctx->fd;
  227. if (task == NULL || file == NULL)
  228. return 0;
  229. if (ctx->meta->seq_num == 0) {
  230. BPF_SEQ_PRINTF(seq, " tgid pid fd file\n");
  231. }
  232. BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd,
  233. (long)file->f_op);
  234. return 0;
  235. }
  236. ----------------------------------------
  237. Creating a File Iterator with Parameters
  238. ----------------------------------------
  239. Now, let us look at how to create an iterator that includes only files of a
  240. process.
  241. First, fill the ``bpf_iter_attach_opts`` struct as shown below:
  242. ::
  243. LIBBPF_OPTS(bpf_iter_attach_opts, opts);
  244. union bpf_iter_link_info linfo;
  245. memset(&linfo, 0, sizeof(linfo));
  246. linfo.task.pid = getpid();
  247. opts.link_info = &linfo;
  248. opts.link_info_len = sizeof(linfo);
  249. ``linfo.task.pid``, if it is non-zero, directs the kernel to create an iterator
  250. that only includes opened files for the process with the specified ``pid``. In
  251. this example, we will only be iterating files for our process. If
  252. ``linfo.task.pid`` is zero, the iterator will visit every opened file of every
  253. process. Similarly, ``linfo.task.tid`` directs the kernel to create an iterator
  254. that visits opened files of a specific thread, not a process. In this example,
  255. ``linfo.task.tid`` is different from ``linfo.task.pid`` only if the thread has a
  256. separate file descriptor table. In most circumstances, all process threads share
  257. a single file descriptor table.
  258. Now, in the userspace program, pass the pointer of struct to the
  259. ``bpf_program__attach_iter()``.
  260. ::
  261. link = bpf_program__attach_iter(prog, &opts); iter_fd =
  262. bpf_iter_create(bpf_link__fd(link));
  263. If both *tid* and *pid* are zero, an iterator created from this struct
  264. ``bpf_iter_attach_opts`` will include every opened file of every task in the
  265. system (in the namespace, actually.) It is the same as passing a NULL as the
  266. second argument to ``bpf_program__attach_iter()``.
  267. The whole program looks like the following code:
  268. ::
  269. #include <stdio.h>
  270. #include <unistd.h>
  271. #include <bpf/bpf.h>
  272. #include <bpf/libbpf.h>
  273. #include "bpf_iter_task_ex.skel.h"
  274. static int do_read_opts(struct bpf_program *prog, struct bpf_iter_attach_opts *opts)
  275. {
  276. struct bpf_link *link;
  277. char buf[16] = {};
  278. int iter_fd = -1, len;
  279. int ret = 0;
  280. link = bpf_program__attach_iter(prog, opts);
  281. if (!link) {
  282. fprintf(stderr, "bpf_program__attach_iter() fails\n");
  283. return -1;
  284. }
  285. iter_fd = bpf_iter_create(bpf_link__fd(link));
  286. if (iter_fd < 0) {
  287. fprintf(stderr, "bpf_iter_create() fails\n");
  288. ret = -1;
  289. goto free_link;
  290. }
  291. /* not check contents, but ensure read() ends without error */
  292. while ((len = read(iter_fd, buf, sizeof(buf) - 1)) > 0) {
  293. buf[len] = 0;
  294. printf("%s", buf);
  295. }
  296. printf("\n");
  297. free_link:
  298. if (iter_fd >= 0)
  299. close(iter_fd);
  300. bpf_link__destroy(link);
  301. return 0;
  302. }
  303. static void test_task_file(void)
  304. {
  305. LIBBPF_OPTS(bpf_iter_attach_opts, opts);
  306. struct bpf_iter_task_ex *skel;
  307. union bpf_iter_link_info linfo;
  308. skel = bpf_iter_task_ex__open_and_load();
  309. if (skel == NULL)
  310. return;
  311. memset(&linfo, 0, sizeof(linfo));
  312. linfo.task.pid = getpid();
  313. opts.link_info = &linfo;
  314. opts.link_info_len = sizeof(linfo);
  315. printf("PID %d\n", getpid());
  316. do_read_opts(skel->progs.dump_task_file, &opts);
  317. bpf_iter_task_ex__destroy(skel);
  318. }
  319. int main(int argc, const char * const * argv)
  320. {
  321. test_task_file();
  322. return 0;
  323. }
  324. The following lines are the output of the program.
  325. ::
  326. PID 1859
  327. tgid pid fd file
  328. 1859 1859 0 ffffffff82270aa0
  329. 1859 1859 1 ffffffff82270aa0
  330. 1859 1859 2 ffffffff82270aa0
  331. 1859 1859 3 ffffffff82272980
  332. 1859 1859 4 ffffffff8225e120
  333. 1859 1859 5 ffffffff82255120
  334. 1859 1859 6 ffffffff82254f00
  335. 1859 1859 7 ffffffff82254d80
  336. 1859 1859 8 ffffffff8225abe0
  337. ------------------
  338. Without Parameters
  339. ------------------
  340. Let us look at how a BPF iterator without parameters skips files of other
  341. processes in the system. In this case, the BPF program has to check the pid or
  342. the tid of tasks, or it will receive every opened file in the system (in the
  343. current *pid* namespace, actually). So, we usually add a global variable in the
  344. BPF program to pass a *pid* to the BPF program.
  345. The BPF program would look like the following block.
  346. ::
  347. ......
  348. int target_pid = 0;
  349. SEC("iter/task_file")
  350. int dump_task_file(struct bpf_iter__task_file *ctx)
  351. {
  352. ......
  353. if (task->tgid != target_pid) /* Check task->pid instead to check thread IDs */
  354. return 0;
  355. BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd,
  356. (long)file->f_op);
  357. return 0;
  358. }
  359. The user space program would look like the following block:
  360. ::
  361. ......
  362. static void test_task_file(void)
  363. {
  364. ......
  365. skel = bpf_iter_task_ex__open_and_load();
  366. if (skel == NULL)
  367. return;
  368. skel->bss->target_pid = getpid(); /* process ID. For thread id, use gettid() */
  369. memset(&linfo, 0, sizeof(linfo));
  370. linfo.task.pid = getpid();
  371. opts.link_info = &linfo;
  372. opts.link_info_len = sizeof(linfo);
  373. ......
  374. }
  375. ``target_pid`` is a global variable in the BPF program. The user space program
  376. should initialize the variable with a process ID to skip opened files of other
  377. processes in the BPF program. When you parametrize a BPF iterator, the iterator
  378. calls the BPF program fewer times which can save significant resources.
  379. ---------------------------
  380. Parametrizing VMA Iterators
  381. ---------------------------
  382. By default, a BPF VMA iterator includes every VMA in every process. However,
  383. you can still specify a process or a thread to include only its VMAs. Unlike
  384. files, a thread can not have a separate address space (since Linux 2.6.0-test6).
  385. Here, using *tid* makes no difference from using *pid*.
  386. ----------------------------
  387. Parametrizing Task Iterators
  388. ----------------------------
  389. A BPF task iterator with *pid* includes all tasks (threads) of a process. The
  390. BPF program receives these tasks one after another. You can specify a BPF task
  391. iterator with *tid* parameter to include only the tasks that match the given
  392. *tid*.