Infiniband

Материал из ALT Linux Wiki

В данной статье описывается настройка 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.
  • В ряде случаев полезно отключить вытесняющую многозадачность.