【发布时间】:2021-05-28 02:58:19
【问题描述】:
我有一个跟踪许多活动 TCP 连接的 kprobe ebpf 程序。为了减少开销,我对可以同时跟踪的 TCP 连接数设置了一个上限。因此,我必须在 ebpf 程序中维护一个计数器,以便在建立新连接时,如果低于限制,则增加计数器,当连接完成时,减少计数器。由于程序是可重入的,所以计数器的操作应该是原子的。
我尝试了 bpf_spin_lock。但是它不能用于跟踪程序(例如 kprobe)。 ebpf 也很少有原子操作。我知道一个操作__sync_fetch_and_add。但是仅仅实现这里的逻辑是不够的。
我在网上找到了一些讨论https://lists.iovisor.org/g/iovisor-dev/topic/bpf_concurrency/74407447?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,20,74407447。在没有任何可行的解决方案的情况下,讨论仍在进行中。
有现成的解决方案吗?非常感谢!
【问题讨论】:
-
如果目标只是限制开销,为什么不使用 per-cpu 阵列来维护每个核心的计数?
-
per-cpu array 只能限制每个cpu的数量。可能会出现以下情况:cpu A 达到其限制,连接被拒绝,而 cpu B 仍有空闲插槽。我需要的是一个全局计数器。
-
如果有问题的开销是 CPU 周期,那么它也是每个核心的开销,所以我看不出有每个核心阈值的问题。您将如何决定什么是好的全局计数器?
-
每个 cpu 计数器的一个问题如下。在一个 kprobe 中,我在建立连接时增加计数器。在另一个 kprobe 中,当连接完成时,我会减少计数器。然而,这两个 kprobe 可以由不同的 cpu 内核运行。这导致计数器在一个 cpu 上增加,而在另一个 cpu 上减少。换句话说,计数器计数不正确。有没有办法解决这个问题?
-
啊,说得好!我假设您必须有一个哈希图来跟踪已建立的连接。如果您只是将该哈希图的 max_entries 设置为全局计数器值怎么办?然后,如果 hashmap 更新失败,则意味着您已达到最大连接数。