动态更改 eBPF 映射大小

Dynamically Change eBPF map size

在内核中,eBPF映射可以定义为:

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(uint32_t),
    .value_size = sizeof(struct task_prov_struct),
    .max_entries = 4096,
};

如果我事先不知道 my_map 的最大可能大小(我也不想浪费内存),有没有办法,比如说,预先分配一个小尺寸和根据需要动态增加大小? 我知道 bpf_map__resize 函数,但它似乎是一个用户 space 函数,只能在加载地图之前调用。 我将不胜感激任何示例代码片段或参考。

不,目前 您无法在 eBPF 映射 创建后“调整其大小”。

但是,内核中映射的大小可能会随时间变化。

  • 一些地图是 pre-allocated,因为它们的类型需要这样(例如数组),或者因为用户在创建地图时通过提供相关标志要求这样做。这些map一创建就分配,占用space等于(key_size + value_size) * max_entries.
  • 其他一些地图不是 pre-allocated,并且会随着时间的推移而增长。例如,哈希映射就是这种情况:随着新条目的添加,它们将在内核 space 中占用更多 space。但是,它们只会增长到在创建期间提供的最大条目数,并且不可能在那之后更新这个最大条目数。

关于 libbpf 的 bpf_map__resize() 函数,它是一个用户 space 函数,可用于更新地图的条目数,before 这个映射是在内核中创建的:

int bpf_map__set_max_entries(struct bpf_map *map, __u32 max_entries)
{
    if (map->fd >= 0)
        return -EBUSY;
    map->def.max_entries = max_entries;
    return 0;
}

int bpf_map__resize(struct bpf_map *map, __u32 max_entries)
{
    if (!map || !max_entries)
        return -EINVAL;

    return bpf_map__set_max_entries(map, max_entries);
}

如果我们已经创建了地图(如果我们有该地图的文件描述符),操作将失败。