Динамическое изменение размера карты eBPF - PullRequest
2 голосов
/ 05 августа 2020

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

1 Ответ

2 голосов
/ 05 августа 2020

Нет, на данный момент вы не можете «изменить размер» карты eBPF после того, как она была создана.

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

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

Что касается 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);
}

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

...