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
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

Теперь можно проверить корректность инициализации 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

  1. ibv_devinfo

Должен видеть устройство (большой вывод) и:

  • на подключенном порте должно быть:

state: PORT_ACTIVE (4) ...

   link_layer:             InfiniBand

было link_layer: Ethernet, т.е. IB сети у них не было совсем, и subnet manager, вероятно, тоже.

5. Создаём eth сеть поверх ib посредством ip-over-ib. Она нужна для инициализации соединений и обмена данными между узлами. Сама пересылка данных при этом идёт по IB.

На первом узле:

  1. ip addr add 192.168.20.1/24 dev ib0

На втором узле:

  1. ip addr add 192.168.20.2/24 dev ib0

IP/подсети можно на вкус выбирать, активное устройство может быть и не ib0, нужно проверить. Статус будет up после запуска subnet manager.

6. Проверка работы RDMA.

6.1. Простой IB RDMA ping:

На первом узле (192.168.20.1):

  1. ibv_rc_pingpong -g 0 -d mlx4_0 -i 1

На втором узле:

  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

6.2. Проверка отправки потока данных через RDMA:

На первой машине (сервер):

  1. rping -s -a 192.168.20.1 -v

на второй (клиент):

  1. rping -c -a 192.168.20.1 -v

Будет огромное число строк данных, убивается по ctrl-c.

Один и тот же ip выше — не ошибка, так и должно быть: для сервера — где слушать, для клиента — куда стучаться.

8. Если желают надёжной и быстрой работы IB, cpu frequency scaling, turbo boost и т.п. должны быть выключены. А мы имеем:

  1. cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver

intel_pstate

Это приводит к некорректной работе ряда тестов, впрочем, непосредственно к RDMA не относится. Причина в низких задержках IB и, как следствие, в высокой чувтсвительности к изменению частоты CPU.