V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
SunBK201
V2EX  ›  Linux

如何解决 eBPF sockmap 重定向转发中背压缺失带来的 OOM ?

  •  1
     
  •   SunBK201 ·
    SunBK201 · 3 月 31 日 · 948 次点击

    我在尝试使用 eBPF 的 BPF_PROG_TYPE_SK_SKBBPF_MAP_TYPE_SOCKHASH 实现 socket 的铰接转发,目标是基于 bpf_sk_redirect_hash 将一个 socket 的 ingress 队列数据转发到另一个 socket 的 egress 队列,但是在实际的吞吐量测试时出现了系统 OOM 。

    具体的环境如下:

    1. Linux Kernel 6.8
    2. 2 个 socket 所处网络接口不同,且 2 个网络接口带宽不一致,转发源 socket 所处接口 (测试用的 loopback) 带宽高于目标 socket 所处带宽
    3. 吞吐测试是在 loopback 上使用 netperf 建立源 socket 连接,目标是转发到另一个网络接口的 socket egress 发送队列进行发送
    4. 具体代码可以见 https://github.com/SunBK201/UA3F/blob/v3.3.0/src/internal/bpf/sockmap/sockmap.c

    我的疑问:

    1. 是否是因为由于网络接口带宽不一致(源网络接口产生的流量远大于目标网络接口所能承载发送的网络带宽),再加上 bpf_sk_redirect_hash 没有背压(流量控制),导致数据堆积造成 OOM ?
    2. 如果是因为背压缺失的原因,该如果解决?实现流控 or 这种场景用 eBPF 做不合适?

    希望各位前辈大佬指教!

    11 条回复    2026-03-31 22:35:15 +08:00
    swananan
        1
    swananan  
       17 小时 15 分钟前
    我不太熟悉这个,插个眼,等大哥回复。

    我本来是想 ebpf redirect 是 unix domain socket 场景的优化方案,我看到你出现了 oom 有点震惊,不是有 sk send_buf 之类可以背压保护吗。问了 ai ,说 ebpf redirect 这个实现,直接绕开了这个限制。。。

    我又问了 ai ,说 绕开的原因是什么,ai 说,是因为 ebpf redirect 运行在软中断里面,没有进程上下文可以阻塞,我觉得这个很合理,说服了我。

    那既然这样,就不适合用 ebpf redirect 方案,去解决这种生产者消费者速率不匹配的场景问题了。

    ai 推荐了 splice 和 io-uring 。

    以上是我边搬砖(围观 cc )边水贴问的,耗时不过十几分钟,按我以前的经验,要探索到这个阶段,得花一个晚上。。。
    SunBK201
        2
    SunBK201  
    OP
       13 小时 3 分钟前
    @swananan 感谢回复。其实我之前就是用 splice 做的,用 eBPF 就是想看看能不能再把转发性能提升一些,目前测试看来对于发送时延和 CPU 负载都能有 20% 到 30% 的优化提升,不过目前看来可能只适用于网络接口带宽收发对等的场景。
    openstackceph
        3
    openstackceph  
       11 小时 48 分钟前
    可以分析一下 kmalloc-2048 分配使用情况
    macscsbf
        4
    macscsbf  
       10 小时 20 分钟前
    没看懂需求是什么还有怎么测试,我可以那我机子测试下。
    SunBK201
        5
    SunBK201  
    OP
       6 小时 53 分钟前
    @macscsbf 需求是用 eBPF 加速 socket 铰接转发,主要是用在 TCP socket 代理上,从一个 socket 上读到数据并写到另一个 socket 上,现在主流做法是用 splice 来做,我想试试 eBPF redirect 能够加速,理论上除了能够零拷贝还能节省系统调用带来的用户态与内核态之间的上下文切换开销。

    如果要测试可以参考下我的代码:
    1. eBPF 程序 https://github.com/SunBK201/UA3F/blob/v3.3.0/src/internal/bpf/sockmap/sockmap.c
    2. 核心就是保存 2 个 socket 的 cookie 到 SOCKHASH ,然后用 `bpf_sk_redirect_hash` 转发
    3. 可以在本机使用 iperf3 或者 netperf 做吞吐测试
    4. 如果要完整复现可能比较麻烦,因为我还用到了 TPORXY ,可以直接用我的项目试试 https://github.com/SunBK201/UA3F ,`go run . -m TPROXY --include-lan-routes`。这个命令会接管本机的所有 TCP 连接并进行代理,然后在本机使用 iperf3 请求到另一台机器即可。
    buffzty
        6
    buffzty  
       6 小时 28 分钟前
    技术问题发到技术论坛
    macscsbf
        7
    macscsbf  
       6 小时 16 分钟前
    @SunBK201 #5 ok ,我看看。
    macscsbf
        8
    macscsbf  
       6 小时 16 分钟前
    @SunBK201 #5 虚拟机可以不
    SunBK201
        9
    SunBK201  
    OP
       6 小时 3 分钟前
    @macscsbf 虚拟机没问题,我就是用的 UTM 复现的
    SunBK201
        10
    SunBK201  
    OP
       5 小时 54 分钟前
    @macscsbf 更正下命令,应该使用命令 go run . -m TPROXY --rewrite-mode DIRECT --include-lan-routes --bpf-offload
    SunBK201
        11
    SunBK201  
    OP
       5 小时 51 分钟前
    @SunBK201 或者 go run . -m TPROXY --rewrite-mode GLOBAL --include-lan-routes --bpf-offload
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   930 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 20:26 · PVG 04:26 · LAX 13:26 · JFK 16:26
    ♥ Do have faith in what you're doing.