Каковы ограничения виртуальной машины bpf и карты bpf?

Я использую ebpf+XDP для создания демонстрации.

когда я использую большую КАРТУ памяти, например:

BPF_HASH(cache, u64, u64, 10240000);
BPF_HASH(filter1, u32, u64, 10240000);
BPF_HASH(filter2, struct XXX, u16, 10240000);

когда я запускаю эту демонстрацию, через некоторое время программа автоматически закрывается.

вот ошибка сказала:

Out of memory: KIll process 1618 (sshd) score 0 or sacrifice child
Killed process 1618 (sshd) total-vm:625792kB, anon-rss:0kB, file-rss:4kB, shmem-rss:0kB

Я не понимаю, какую дозу означает эта ошибка.

Это ограничение системы или ограничение bpf vm или ограничение карты?

Вот результат, когда я запускаю «free -g».

              total        used        free      shared  buff/cache   available
Mem:              3           0           3           0           0           3
Swap:             3           0           3

person Vector    schedule 17.01.2020    source источник
comment
Я не могу воспроизвести. Не могли бы вы опубликовать реальный, минимальный репродукционный случай? Кроме того, какую версию bcc вы используете?   -  person pchaigno    schedule 17.01.2020


Ответы (1)


Когда вы создаете карты BPF, для этих карт выделяется память в пространстве ядра. Очевидно, что чем они больше, тем больше памяти требуется.

Хотя BPF практически не имеет ограничений на размер карт (кроме максимального значения для 32-битного целого числа без знака, которое передается ядру для определения размера карты), само ядро ​​имеет ограничения, связанные с базовым оборудованием. Если бы ядру полностью не хватило памяти, Произошли бы Плохие Вещи. Как правило, он зависал или зависал. Чтобы избежать этого, когда памяти становится мало, убийца нехватки памяти (OOM) вступает в действие и убивает процесс, как попытку освободить память.

Насколько я понимаю, в вашем случае происходит именно так. Ограничение не из-за BPF или карт BPF, а просто из-за нехватки памяти в вашей системе (ядре). Вы можете получить больше информации в журналах ядра с помощью dmesg, когда происходит уничтожение (см. также как прочитать журналы).

Итак, чтобы ответить на вопрос, как вы сформулировали в заголовке: карты BPF не ограничены в размере, кроме максимального значения, которое мы можем передать системному вызову bpf() (uint_32, так что это около 4 ГБ). Пользователи без полномочий root могут иметь дополнительные ограничения на объем пространства, которое они могут заблокировать в ядре (root может снять эти ограничения с помощью ulimit -l в оболочке или setrlimit() в программе на C). Существуют и другие «ограничения» для инфраструктуры BPF (размер стека, количество хвостовых вызовов и т. д.), но я не думаю, что перечисление их всех здесь сильно поможет. Дополнительную информацию о них можно найти в руководстве по Cilium.

person Qeole    schedule 17.01.2020
comment
Привет @Qeole, в исходном коде ядра здесь, он утверждает, что карта слишком велика, если size >= U32_MAX - PAGE_SIZE, знаете ли вы причину, по которой внутри оператора есть - PAGE_SIZE? То есть есть ли причина, чтобы размер не превышал 4GB - 4KB (скажем арка амд64) вместо просто 4гб памяти? Спасибо! - person Feng. Ma; 14.06.2021
comment
Правильно, я пропустил тот чек в то время, когда я ответил. До того, как эта проверка была перемещена в syscall.c, она раньше сопровождался комментарием: /* make sure there is no u32 overflow later in round_up() */. Итак, я понимаю, что окончательный фактический размер округляется от значения, переданного пользователем, чтобы убедиться, что оно кратно PAGE_SIZE. Поэтому нам нужно убедиться, что это округление не приведет к переполнению. - person Qeole; 14.06.2021