Infiniband
В данной статье описывается настройка InfiniBand и RDMA на его основе для c7 и адаптеров ConnectX-3. Но основная последовательность действий в другой среде будет такой же, различия могут быть в именах пакетов и особенностях драйверов.
Список пакетов для установки
Важно понимать, что IB предоставляет возможность работы с железом преимущественно из юзерспейса, в обход ядра (переключения из пространства ядра в пространство пользователя слишком дорогое и неприемлемо на low-latency системах), так что драйвера в одном ядре мало.
Необходимы для работы:
ядро, собранной с поддержкой нужных IB устройств (в нашем случае mlx4_core, mlx4_ib) libmlx4 — OFED компонента драйвера для Mellanox ConnectX HCA (юзерспейс) libibverbs librdmacm libibumad libibcm libibmad
Некоторые из указанных выше компонент могут не понадобится на узких задачах, но для облегчения настройки и отладки лучше поставить всё.
Это список утилит для работы с IB, отладки и тестирования, лучше поставить все:
libibverbs-utils librdmacm-utils perftest libopensm2 libinfiniband-diags infiniband-diags
Размер MTT таблицы
У драйвера IB адаптера есть один важный параметр: Memory Translation Table (MTT) — это таблица отображения страниц виртуальной памяти в реальную. Для работы RDMA размер MTT должен быть не меньше размера физической памяти системы, рекомендуется удвоенный размер для улучшенной обработки фрагментации и иных проблем), подробнее в руководстве open-mpi, документации melanox и ibm.
Конкретные ошибки могут возникать разные, но все они будут связаны с невозможностью работы RDMA или MPI. В документации выше описано решение, но оно верно для старых ядер, в сколь-либо современных (как минимум начиная с 3.x) параметры модуля mlx4_core ядра иные (log_num_mtt нет) и считать нужно немного иначе. Следует обратить внимание, что от слишком большого значения на машине с малым количеством памяти также вредно, т.к. уменьшит эффективность её использования.
По состоянию на ядро 4.14 у модуля mlx4_core есть один релевантный параметр log_mtts_per_seg, который задаётся в виде показателя экспоненты по основанию 2 и по-умолчанию равен 3. Эмпирическим путём было установлено, что достаточным является соотношение: full ram = 4GB * 2^log_mtts_per_seg, при этом максимально возможным значением, заложенным в драйвере является 7. Поэтому рекомендуется задавать log_mtts_per_seg = ⌈RAM/4GB⌉+1 для RAM <= 256 GB и log_mtts_per_seg = 7 для RAM >= 256 GB. (⌈x⌉ — округление вверх).
Итак, передаём нужный параметр модулю ядра при его загрузке:
# cat /etc/modprobe.d/ib.conf options mlx4_core log_mtts_per_seg=7
На других моделях карт или производителей могут быть похожие проблемы, поэтому следует уделять особое внимание размеру MTT при возникновении проблем с RDMA или MPI.
Загрузка модулей ядра
Необходимо загрузить следующие модули (и добавить в /etc/modules):
mlx4_ib — для карт Mellanox < ConnectX-5, для остальных производителей нужны свои ib_ipoib rdma_ucm ib_ucm // NB: удалён из Linux 5.3 ib_uverbs ib_umad rdma_cm ib_cm ib_mad iw_cm
Проверка на этом этапе, ibv должен видеть устройство:
# ibv_devices device node GUID ------ ---------------- mlx4_0 248a07030069dfa0
Менеджер подсети
Каждой сети Infiniband должен быть хотя бы один менеджер подсети (subnet manager). Часто его функции выполняет IB-свитч, но его может и не быть (например, соединение карта <-> карта) или он может быть ограничен по функциональности и нежелателен к использованию. Здесь рассматривается установка и настройка для простейшей топологии OpenSM.
На одном из узлов сети следует:
- Установить opensm2.
- Прописать в /etc/sysconfig/opensm:
OSM_HOSTS=hostname
где hostname — имя хоста, возвращаемое командой $ hostname
- Запустить opensm:
/etc/init.d/opensm start
- Проверить, что демон в автозагрузке:
chkconfig --list opensm
Следует отметить, что OpenSM способен обеспечивать топологию и маршрутизацию любой сложности, включая толстое дерево и многомерный tor, для каждой подсети такой топологии будет работать свой OpenSM. Подробности можно посмотреть в руководстве man opensm. При необходимости тонкой настройки рекомендуется создать полную конфигурацию opensm по-умолчанию с помощью opensm -c myopensmconf.conf.
Теперь можно проверить корректность инициализации IB сети:
#ibv_devinfo hca_id: mlx4_0 transport: InfiniBand (0) fw_ver: 2.42.5000 node_guid: 248a:0703:0069:dfa0 sys_image_guid: 248a:0703:0069:dfa3 vendor_id: 0x02c9 vendor_part_id: 4103 hw_ver: 0x0 board_id: MT_1090111019 phys_port_cnt: 2 port: 1 state: PORT_ACTIVE (4) max_mtu: 4096 (5) active_mtu: 4096 (5) sm_lid: 1 port_lid: 2 port_lmc: 0x00 link_layer: InfiniBand port: 2 state: PORT_DOWN (1) max_mtu: 4096 (5) active_mtu: 4096 (5) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: InfiniBand
Следует обратить внимание на следующие параметры на подключенном порте:
state: PORT_ACTIVE (4) link_layer: InfiniBand
PORT_DOWN означает выключенный порт и/или отсутствие физического соединения.
PORT_INIT означает, что соединение есть, но находится в состоянии инициализации и ещё не готово к работе. Это часто бывает, если в сети нет subnet manager'а.
PORT_ACTIVE означает, что порт готов к работе.
Если link_layer: Ethernet или любой другой слой, кроме Infiniband, это означает, что поднят RDMA по другому протоколу, например, RDMA over Converged Ethernet (RoCE) и Infiniband не работает. Такое может быть на Mellanox картах с VPI интерфейсами (они могут работать как в режиме IB, так и в режиме CE).
IP over IB
Для приложений, работающих через lid/guid, в принципе, сделанной конфигурации достаточно. Но большинство приложений использует IP стек, поднятый поверх IB для инициализации соединений и получения части информации о конфигурации сети, поэтому желательно его тоже настроить. Следует обратить внимание, что передавать основные данные по ipoib 'нельзя, т.к. все достоинства IB по низким задержкам и издержкам стек IP убивает напрочь — это распространённая ошибка при конфигурации сетей Infiniband. Корректная настройка зависит от конкретного приложения, но её показателями являются:
- использование ibverbs приложением;
- отсутствие существенного трафика на ib* интерфейсах при передаче больших объёмов данных.
Рассмотрим настройку ipoib на примере двух узлов сети.
На первом узле:
# ip addr add 192.168.20.1/24 dev ib0
На втором узле:
# ip addr add 192.168.20.2/24 dev ib0
IP/подсети можно на вкус выбирать, при наличии нескольких портов или адаптеров активное устройство может быть и не ib0, нужно проверить. Статус будет up после запуска subnet manager.
Настройки интерфейсов следует сохранить точно так же, как и обычные сетевые настройки с использованием etcnet.
Проверить работу можно обычным ping с одного узла на другой.
Проверка работы RDMA
Простой IB RDMA ping
На первом узле (192.168.20.1):
# ibv_rc_pingpong -g 0 -d mlx4_0 -i 1
На втором узле:
# ibv_rc_pingpong -g 0 -d mlx4_0 -i 1 192.168.20.1
где цифра после -i — номер активного порта, можно посмотреть в ibv_devinfo.
После запуска второй команды должна быть информация об обмене данными, вывод похож на обоих узлах:
local address: LID 0x0001, QPN 0x00004e, PSN 0xdfe7bc, GID fe80::248a:703:69:e001 remote address: LID 0x0002, QPN 0x00004f, PSN 0x212ee1, GID fe80::248a:703:69:dfa1 8192000 bytes in 0.01 seconds = 11638.43 Mbit/sec 1000 iters in 0.01 seconds = 5.63 usec/iter
Проверка отправки потока данных через RDMA
На первой машине (сервер):
# rping -s -a 192.168.20.1 -v
на второй (клиент):
# rping -c -a 192.168.20.1 -v
Будет большое число строк данных вида ротации строк:
ping data: rdma-ping-11278: [\]^_`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN ping data: rdma-ping-11279: \]^_`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO ping data: rdma-ping-11280: ]^_`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP ping data: rdma-ping-11281: ^_`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ ping data: rdma-ping-11282: _`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR
убивается по ctrl-c.
Один и тот же ip выше — не ошибка, так и должно быть: для сервера — где слушать, для клиента — куда стучаться.
Настройка оборудования IB узлов
Infiniband работает на предельно низких задержках и предельно высоких скоростей (для обмена между узлами), поэтому для оптимальной работы технологии необходима тонкая настройка иных компонент.
CPU
Измнение частоты работы CPU плохо влияет на задержки работы IB, т.к. передача данных может быть привязана к скорости циклов CPU, особо плохо, когда скорость меняется неравномерно и неодновременно на разных узлах. Поэтому следует:
- выключить cpu frequency scaling;
- выключить turboboost;
- отключить hyperthreading;
- отключить виртуализацию и, желательно, контейнеры;
- отключить глубокие C-states, лучшее вообще всё ниже C1E запретить;
- отключить P-states;
- QPI, NUMA и т.п. технлогии, следует их настроить на работу в режиме minimum latency.
BIOS / UEFI
- Включить HPC mode в BIOS, если есть.
- Всё остальное перевести в режим performance.
- Отключить энергосбережение, особенно агрессивное.
- Настроить память на minimum latency.
- Помогает подбор режима memory interleaving. Для тестов памяти хорошо подходит ramspeed.
Ядро
- Следует убедится, что включены DMA engine, в частности, DMA I/O offload для сетевых адаптеров.
- Включить DCA (direct cache access) — аналог DMA для доступа к кешу CPU.
- В ряде случаев полезно отключить вытесняющую многозадачность.