跳转至

bpf/verifier: Optimize ID mapping reset in states_equal

问题背景

BPF verifier 在进行状态等价性比较 (states_equal()) 时,需要维护一个 ID 映射表 (bpf_idmap) 来跟踪两个状态中的寄存器 ID 对应关系。每次调用 states_equal() 时,reset_idmap_scratch() 会对整个 4.7KB 的映射表执行 memset() 清零操作。

在高频路径中(例如程序包含大量分支和循环),states_equal() 可能被调用数万甚至数十万次,每次 4.7KB 的 memset 累积起来成为 verifier 的主要性能瓶颈之一。

优化方案

引入 cnt 计数器追踪 idmap 中已使用的槽位数:

check_ids() 优化: - 原来:固定遍历 BPF_ID_MAP_SIZE(1024)个槽位 - 现在:只遍历 idmap->cnt 个已使用的槽位 - 新 ID 对直接追加到 map[idmap->cnt],然后 cnt++

reset_idmap_scratch() 优化: - 原来:memset(&env->idmap_scratch.map, 0, 4.7KB) - 现在:idmap->cnt = 0 (O(1) 重置)

代码变更

文件 变更
include/linux/bpf_verifier.h struct bpf_idmap 新增 u32 cnt 字段
kernel/bpf/verifier.c check_ids() 搜索循环受限于 cntreset_idmap_scratch()cnt=0 替代 memset()
// 优化前
static void reset_idmap_scratch(struct bpf_verifier_env *env)
{
    env->idmap_scratch.tmp_id_gen = env->id_gen;
    memset(&env->idmap_scratch.map, 0, sizeof(env->idmap_scratch.map));
}

// 优化后
static void reset_idmap_scratch(struct bpf_verifier_env *env)
{
    struct bpf_idmap *idmap = &env->idmap_scratch;
    idmap->tmp_id_gen = env->id_gen;
    idmap->cnt = 0;
}

上游状态

  • Lore: https://lore.kernel.org/bpf/20260120023234.77673-1-realwujing@gmail.com
  • 合入: torvalds/master f81c07a6e98e
  • 合入者: Andrii Nakryiko andrii@kernel.org
  • Acked-by: Eduard Zingerman eddyz87@gmail.com

💬 评论