Динамическое изменение размера карты eBPF

В ядре карты 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, но, похоже, это функция пользовательского пространства, и ее можно вызывать только до загрузки карты. Я был бы признателен за любой образец кода или ссылку.


person vanbastelaer    schedule 05.08.2020    source источник


Ответы (1)


Нет, в настоящее время вы не можете изменить размер карты eBPF после ее создания.

Однако размер карты в ядре может меняться со временем.

  • Некоторые карты предварительно распределены, потому что этого требует их тип (например, массивы) или потому, что это требовалось пользователем во время создания карты, путем предоставления соответствующего флага. Эти карты выделяются сразу после их создания и занимают место, равное (key_size + value_size) * max_entries.
  • Некоторые другие карты не распределены заранее и со временем будут расти. Это относится, например, к хеш-картам: они будут занимать больше места в пространстве ядра по мере добавления новых записей. Однако они будут увеличиваться только до максимального количества записей, указанного при их создании, и после этого НЕ невозможно обновить это максимальное количество записей.

Что касается функции bpf_map__resize() из libbpf, это функция пользовательского пространства, которую можно использовать для обновления количества записей для карты до создания этой карты в ядре:

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);
}

Если мы уже создали карту (если у нас есть дескриптор файла для этой карты), операция завершится ошибкой.

person Qeole    schedule 05.08.2020