动态更改 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);
}
如果我们已经创建了地图(如果我们有该地图的文件描述符),操作将失败。
在内核中,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);
}
如果我们已经创建了地图(如果我们有该地图的文件描述符),操作将失败。