BPF List
 help / color / mirror / Atom feed
From: David Marchevsky <david.marchevsky@linux.dev>
To: Dave Marchevsky <davemarchevsky@fb.com>, bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Kernel Team <kernel-team@fb.com>
Subject: Re: [PATCH v7 bpf-next 0/5] Open-coded task_vma iter
Date: Fri, 13 Oct 2023 16:48:02 -0400	[thread overview]
Message-ID: <17453ff8-895b-4684-9c7d-2c64d82cf9e1@linux.dev> (raw)
In-Reply-To: <20231013204426.1074286-1-davemarchevsky@fb.com>

On 10/13/23 4:44 PM, Dave Marchevsky wrote:
> At Meta we have a profiling daemon which periodically collects
> information on many hosts. This collection usually involves grabbing
> stacks (user and kernel) using perf_event BPF progs and later symbolicating
> them. For user stacks we try to use BPF_F_USER_BUILD_ID and rely on
> remote symbolication, but BPF_F_USER_BUILD_ID doesn't always succeed. In
> those cases we must fall back to digging around in /proc/PID/maps to map
> virtual address to (binary, offset). The /proc/PID/maps digging does not
> occur synchronously with stack collection, so the process might already
> be gone, in which case it won't have /proc/PID/maps and we will fail to
> symbolicate.
> 
> This 'exited process problem' doesn't occur very often as
> most of the prod services we care to profile are long-lived daemons, but
> there are enough usecases to warrant a workaround: a BPF program which
> can be optionally loaded at data collection time and essentially walks
> /proc/PID/maps. Currently this is done by walking the vma list:
> 
>   struct vm_area_struct* mmap = BPF_CORE_READ(mm, mmap);
>   mmap_next = BPF_CORE_READ(rmap, vm_next); /* in a loop */
> 
> Since commit 763ecb035029 ("mm: remove the vma linked list") there's no
> longer a vma linked list to walk. Walking the vma maple tree is not as
> simple as hopping struct vm_area_struct->vm_next. Luckily,
> commit f39af05949a4 ("mm: add VMA iterator"), another commit in that series,
> added struct vma_iterator and for_each_vma macro for easy vma iteration. If
> similar functionality was exposed to BPF programs, it would be perfect for our
> usecase.
> 
> This series adds such functionality, specifically a BPF equivalent of
> for_each_vma using the open-coded iterator style.
> 
> Notes:
>   * This approach was chosen after discussion on a previous series [0] which
>     attempted to solve the same problem by adding a BPF_F_VMA_NEXT flag to
>     bpf_find_vma.
>   * Unlike the task_vma bpf_iter, the open-coded iterator kfuncs here do not
>     drop the vma read lock between iterations. See Alexei's response in [0].
>   * The [vsyscall] page isn't really part of task->mm's vmas, but
>     /proc/PID/maps returns information about it anyways. The vma iter added
>     here does not do the same. See comment on selftest in patch 3.
>   * bpf_iter_task_vma allocates a _data struct which contains - among other
>     things - struct vma_iterator, using BPF allocator and keeps a pointer to
>     the bpf_iter_task_vma_data. This is done in order to prevent changes to
>     struct ma_state - which is wrapped by struct vma_iterator - from
>     necessitating changes to uapi struct bpf_iter_task_vma.
> 
> Changelog:
> 
> v6 -> v7: https://lore.kernel.org/bpf/20231010185944.3888849-1-davemarchevsky@fb.com/
> 
> Patch numbers correspond to their position in v6
> 
> Patch 2 ("selftests/bpf: Rename bpf_iter_task_vma.c to bpf_iter_task_vmas.c")
>   * Add Andrii ack
> Patch 3 ("bpf: Introduce task_vma open-coded iterator kfuncs")
>   * Add Andrii ack
>   * Add missing __diag_ignore_all for -Wmissing-prototypes (Song)
> Patch 4 ("selftests/bpf: Add tests for open-coded task_vma iter")
>   * Remove two unnecessary header includes (Andrii)
>   * Remove extraneous !vmas_seen check (Andrii)

Whoops, forgot to add another bullet here:
  * Initialize FILE *f = NULL to address llvm-16 CI warnings (Andrii)

> New Patch ("bpf: Add BPF_KFUNC_{START,END}_defs macros")
>   * After talking to Andrii, this is an attempt to clean up __diag_ignore_all
>     spam everywhere kfuncs are defined. If nontrivial changes are needed,
>     let's apply the other 4 and I'll respin as a standalone patch.
> 
> v5 -> v6: https://lore.kernel.org/bpf/20231010175637.3405682-1-davemarchevsky@fb.com/
> 
> Patch 4 ("selftests/bpf: Add tests for open-coded task_vma iter")
>   * Remove extraneous blank line. I did this manually to the .patch file
>     for v5, which caused BPF CI to complain about failing to apply the
>     series
> 
> v4 -> v5: https://lore.kernel.org/bpf/20231002195341.2940874-1-davemarchevsky@fb.com/
> 
> Patch numbers correspond to their position in v4
> 
> New Patch ("selftests/bpf: Rename bpf_iter_task_vma.c to bpf_iter_task_vmas.c")
>   * Patch 2's renaming of this selftest, and associated changes in the
>     userspace runner, are split out into this separate commit (Andrii)
> 
> Patch 2 ("bpf: Introduce task_vma open-coded iterator kfuncs")
>   * Remove bpf_iter_task_vma kfuncs from libbpf's bpf_helpers.h, they'll be
>     added to selftests' bpf_experimental.h in selftests patch below (Andrii)
>   * Split bpf_iter_task_vma.c renaming into separate commit (Andrii)
> 
> Patch 3 ("selftests/bpf: Add tests for open-coded task_vma iter")
>   * Add bpf_iter_task_vma kfuncs to bpf_experimental.h (Andrii)
>   * Remove '?' from prog SEC, open_and_load the skel in one operation (Andrii)
>   * Ensure that fclose() always happens in test runner (Andrii)
>   * Use global var w/ 1000 (vm_start, vm_end) structs instead of two
>     MAP_TYPE_ARRAY's w/ 1k u64s each (Andrii)
> 
> 
> v3 -> v4: https://lore.kernel.org/bpf/20230822050558.2937659-1-davemarchevsky@fb.com/
> 
> Patch 1 ("bpf: Don't explicitly emit BTF for struct btf_iter_num")
>   * Add Andrii ack
> Patch 2 ("bpf: Introduce task_vma open-coded iterator kfuncs")
>   * Mark bpf_iter_task_vma_new args KF_RCU and remove now-unnecessary !task
>     check (Yonghong)
>     * Although KF_RCU is a function-level flag, in reality it only applies to
>       the task_struct *task parameter, as the other two params are a scalar int
>       and a specially-handled KF_ARG_PTR_TO_ITER
>    * Remove struct bpf_iter_task_vma definition from uapi headers, define in
>      kernel/bpf/task_iter.c instead (Andrii)
> Patch 3 ("selftests/bpf: Add tests for open-coded task_vma iter")
>   * Use a local var when looping over vmas to track map idx. Update vmas_seen
>     global after done iterating. Don't start iterating or update vmas_seen if
>     vmas_seen global is nonzero. (Andrii)
>   * Move getpgid() call to correct spot - above skel detach. (Andrii)
> 
> v2 -> v3: https://lore.kernel.org/bpf/20230821173415.1970776-1-davemarchevsky@fb.com/
> 
> Patch 1 ("bpf: Don't explicitly emit BTF for struct btf_iter_num")
>   * Add Yonghong ack
> 
> Patch 2 ("bpf: Introduce task_vma open-coded iterator kfuncs")
>   * UAPI bpf header and tools/ version should match
>   * Add bpf_iter_task_vma_kern_data which bpf_iter_task_vma_kern points to,
>     bpf_mem_alloc/free it instead of just vma_iterator. (Alexei)
>     * Inner data ptr == NULL implies initialization failed
> 
> 
> v1 -> v2: https://lore.kernel.org/bpf/20230810183513.684836-1-davemarchevsky@fb.com/
>   * Patch 1
>     * Now removes the unnecessary BTF_TYPE_EMIT instead of changing the
>       type (Yonghong)
>   * Patch 2
>     * Don't do unnecessary BTF_TYPE_EMIT (Yonghong)
>     * Bump task refcount to prevent ->mm reuse (Yonghong)
>     * Keep a pointer to vma_iterator in bpf_iter_task_vma, alloc/free
>       via BPF mem allocator (Yonghong, Stanislav)
>   * Patch 3
> 
>   [0]: https://lore.kernel.org/bpf/20230801145414.418145-1-davemarchevsky@fb.com/
> 
> Dave Marchevsky (5):
>   bpf: Don't explicitly emit BTF for struct btf_iter_num
>   selftests/bpf: Rename bpf_iter_task_vma.c to bpf_iter_task_vmas.c
>   bpf: Introduce task_vma open-coded iterator kfuncs
>   selftests/bpf: Add tests for open-coded task_vma iter
>   bpf: Add BPF_KFUNC_{START,END}_defs macros
> 
>  include/linux/btf.h                           |  7 ++
>  kernel/bpf/bpf_iter.c                         |  8 +-
>  kernel/bpf/cpumask.c                          |  6 +-
>  kernel/bpf/helpers.c                          |  9 +-
>  kernel/bpf/map_iter.c                         |  6 +-
>  kernel/bpf/task_iter.c                        | 89 +++++++++++++++++++
>  kernel/trace/bpf_trace.c                      |  6 +-
>  net/bpf/test_run.c                            |  7 +-
>  net/core/filter.c                             | 13 +--
>  net/core/xdp.c                                |  6 +-
>  net/ipv4/fou_bpf.c                            |  6 +-
>  net/netfilter/nf_conntrack_bpf.c              |  6 +-
>  net/netfilter/nf_nat_bpf.c                    |  6 +-
>  net/xfrm/xfrm_interface_bpf.c                 |  6 +-
>  .../testing/selftests/bpf/bpf_experimental.h  |  8 ++
>  .../selftests/bpf/prog_tests/bpf_iter.c       | 26 +++---
>  .../testing/selftests/bpf/prog_tests/iters.c  | 58 ++++++++++++
>  ...f_iter_task_vma.c => bpf_iter_task_vmas.c} |  0
>  .../selftests/bpf/progs/iters_task_vma.c      | 43 +++++++++
>  19 files changed, 248 insertions(+), 68 deletions(-)
>  rename tools/testing/selftests/bpf/progs/{bpf_iter_task_vma.c => bpf_iter_task_vmas.c} (100%)
>  create mode 100644 tools/testing/selftests/bpf/progs/iters_task_vma.c
> 

  parent reply	other threads:[~2023-10-13 20:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-13 20:44 [PATCH v7 bpf-next 0/5] Open-coded task_vma iter Dave Marchevsky
2023-10-13 20:44 ` [PATCH v7 bpf-next 1/5] bpf: Don't explicitly emit BTF for struct btf_iter_num Dave Marchevsky
2023-10-13 20:44 ` [PATCH v7 bpf-next 2/5] selftests/bpf: Rename bpf_iter_task_vma.c to bpf_iter_task_vmas.c Dave Marchevsky
2023-10-13 20:44 ` [PATCH v7 bpf-next 3/5] bpf: Introduce task_vma open-coded iterator kfuncs Dave Marchevsky
2023-10-13 20:44 ` [PATCH v7 bpf-next 4/5] selftests/bpf: Add tests for open-coded task_vma iter Dave Marchevsky
2023-10-13 20:44 ` [PATCH v7 bpf-next 5/5] bpf: Add BPF_KFUNC_{START,END}_defs macros Dave Marchevsky
2023-10-13 20:48 ` David Marchevsky [this message]
2023-10-13 22:56   ` [PATCH v7 bpf-next 0/5] Open-coded task_vma iter Andrii Nakryiko
2023-10-13 23:00 ` patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=17453ff8-895b-4684-9c7d-2c64d82cf9e1@linux.dev \
    --to=david.marchevsky@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davemarchevsky@fb.com \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox