From ddea31d86ddb340917b9eb82a84d4ba68870df3f Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Tue, 19 Nov 2024 01:54:00 +0300 Subject: [PATCH] Auto-select first RDMA device only if RoCE is not found, add rocev2->rocev1->ib priority --- docs/config/network.en.md | 19 +++++++++++------- docs/config/network.ru.md | 22 ++++++++++++-------- docs/config/src/network.yml | 40 ++++++++++++++++++++++++------------- src/client/msgr_rdma.cpp | 29 +++++++++++++++++++++------ 4 files changed, 75 insertions(+), 35 deletions(-) diff --git a/docs/config/network.en.md b/docs/config/network.en.md index bc9424b8..5ba3f45b 100644 --- a/docs/config/network.en.md +++ b/docs/config/network.en.md @@ -68,11 +68,15 @@ but they are not connected to the cluster. - Type: string RDMA device name to use for Vitastor OSD communications (for example, -"rocep5s0f0"). Now Vitastor supports all adapters, even ones without -ODP support, like Mellanox ConnectX-3 and non-Mellanox cards. +"rocep5s0f0"). If not specified, Vitastor will try to find an RoCE +device matching [osd_network](osd.en.md#osd_network), preferring RoCEv2, +or choose the first available RDMA device if no RoCE devices are +found or if `osd_network` is not specified. -Versions up to Vitastor 1.2.0 required ODP which is only present in -Mellanox ConnectX >= 4. See also [rdma_odp](#rdma_odp). +Vitastor supports all adapters, even ones without ODP support, like +Mellanox ConnectX-3 and non-Mellanox cards. Versions up to Vitastor +1.2.0 required ODP which is only present in Mellanox ConnectX >= 4. +See also [rdma_odp](#rdma_odp). Run `ibv_devinfo -v` as root to list available RDMA devices and their features. @@ -95,15 +99,16 @@ your device has. ## rdma_gid_index - Type: integer -- Default: 0 Global address identifier index of the RDMA device to use. Different GID indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP. Search for "GID" in `ibv_devinfo -v` output to determine which GID index you need. -**IMPORTANT:** If you want to use RoCEv2 (as recommended) then the correct -rdma_gid_index is usually 1 (IPv6) or 3 (IPv4). +If not specified, Vitastor will try to auto-select a RoCEv2 IPv4 GID, then +RoCEv2 IPv6 GID, then RoCEv1 IPv4 GID, then RoCEv1 IPv6 GID, then IB GID. + +A correct rdma_gid_index for RoCEv2 is usually 1 (IPv6) or 3 (IPv4). ## rdma_mtu diff --git a/docs/config/network.ru.md b/docs/config/network.ru.md index b26e58fa..77723fac 100644 --- a/docs/config/network.ru.md +++ b/docs/config/network.ru.md @@ -71,12 +71,16 @@ RDMA может быть нужно только если у клиентов е - Тип: строка Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0"). -Сейчас Vitastor поддерживает все модели адаптеров, включая те, у которых -нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и -картами производства не Mellanox. +Если не указано, Vitastor попробует найти RoCE-устройство, соответствующее +[osd_network](osd.en.md#osd_network), предпочитая RoCEv2, или выбрать первое +попавшееся RDMA-устройство, если RoCE-устройств нет или если сеть `osd_network` +не задана. -Версии Vitastor до 1.2.0 включительно требовали ODP, который есть только -на Mellanox ConnectX 4 и более новых. См. также [rdma_odp](#rdma_odp). +Vitastor поддерживает все модели адаптеров, включая те, у которых +нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и +картами производства не Mellanox. Версии Vitastor до 1.2.0 включительно +требовали ODP, который есть только на Mellanox ConnectX 4 и более новых. +См. также [rdma_odp](#rdma_odp). Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их параметры и возможности. @@ -101,15 +105,17 @@ Control) и ECN (Explicit Congestion Notification). ## rdma_gid_index - Тип: целое число -- Значение по умолчанию: 0 Номер глобального идентификатора адреса RDMA-устройства, который следует использовать. Разным gid_index могут соответствовать разные протоколы связи: RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со словом "GID" в выводе команды `ibv_devinfo -v`. -**ВАЖНО:** Если вы хотите использовать RoCEv2 (как мы и рекомендуем), то -правильный rdma_gid_index, как правило, 1 (IPv6) или 3 (IPv4). +Если не указан, Vitastor попробует автоматически выбрать сначала GID, +соответствующий RoCEv2 IPv4, потом RoCEv2 IPv6, потом RoCEv1 IPv4, потом +RoCEv1 IPv6, потом IB. + +Правильный rdma_gid_index для RoCEv2, как правило, 1 (IPv6) или 3 (IPv4). ## rdma_mtu diff --git a/docs/config/src/network.yml b/docs/config/src/network.yml index 3a3e9c56..a26be402 100644 --- a/docs/config/src/network.yml +++ b/docs/config/src/network.yml @@ -48,11 +48,15 @@ type: string info: | RDMA device name to use for Vitastor OSD communications (for example, - "rocep5s0f0"). Now Vitastor supports all adapters, even ones without - ODP support, like Mellanox ConnectX-3 and non-Mellanox cards. + "rocep5s0f0"). If not specified, Vitastor will try to find an RoCE + device matching [osd_network](osd.en.md#osd_network), preferring RoCEv2, + or choose the first available RDMA device if no RoCE devices are + found or if `osd_network` is not specified. - Versions up to Vitastor 1.2.0 required ODP which is only present in - Mellanox ConnectX >= 4. See also [rdma_odp](#rdma_odp). + Vitastor supports all adapters, even ones without ODP support, like + Mellanox ConnectX-3 and non-Mellanox cards. Versions up to Vitastor + 1.2.0 required ODP which is only present in Mellanox ConnectX >= 4. + See also [rdma_odp](#rdma_odp). Run `ibv_devinfo -v` as root to list available RDMA devices and their features. @@ -64,12 +68,16 @@ PFC (Priority Flow Control) and ECN (Explicit Congestion Notification). info_ru: | Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0"). - Сейчас Vitastor поддерживает все модели адаптеров, включая те, у которых - нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и - картами производства не Mellanox. + Если не указано, Vitastor попробует найти RoCE-устройство, соответствующее + [osd_network](osd.en.md#osd_network), предпочитая RoCEv2, или выбрать первое + попавшееся RDMA-устройство, если RoCE-устройств нет или если сеть `osd_network` + не задана. - Версии Vitastor до 1.2.0 включительно требовали ODP, который есть только - на Mellanox ConnectX 4 и более новых. См. также [rdma_odp](#rdma_odp). + Vitastor поддерживает все модели адаптеров, включая те, у которых + нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и + картами производства не Mellanox. Версии Vitastor до 1.2.0 включительно + требовали ODP, который есть только на Mellanox ConnectX 4 и более новых. + См. также [rdma_odp](#rdma_odp). Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их параметры и возможности. @@ -94,23 +102,27 @@ `ibv_devinfo -v`. - name: rdma_gid_index type: int - default: 0 info: | Global address identifier index of the RDMA device to use. Different GID indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP. Search for "GID" in `ibv_devinfo -v` output to determine which GID index you need. - **IMPORTANT:** If you want to use RoCEv2 (as recommended) then the correct - rdma_gid_index is usually 1 (IPv6) or 3 (IPv4). + If not specified, Vitastor will try to auto-select a RoCEv2 IPv4 GID, then + RoCEv2 IPv6 GID, then RoCEv1 IPv4 GID, then RoCEv1 IPv6 GID, then IB GID. + + A correct rdma_gid_index for RoCEv2 is usually 1 (IPv6) or 3 (IPv4). info_ru: | Номер глобального идентификатора адреса RDMA-устройства, который следует использовать. Разным gid_index могут соответствовать разные протоколы связи: RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со словом "GID" в выводе команды `ibv_devinfo -v`. - **ВАЖНО:** Если вы хотите использовать RoCEv2 (как мы и рекомендуем), то - правильный rdma_gid_index, как правило, 1 (IPv6) или 3 (IPv4). + Если не указан, Vitastor попробует автоматически выбрать сначала GID, + соответствующий RoCEv2 IPv4, потом RoCEv2 IPv6, потом RoCEv1 IPv4, потом + RoCEv1 IPv6, потом IB. + + Правильный rdma_gid_index для RoCEv2, как правило, 1 (IPv6) или 3 (IPv4). - name: rdma_mtu type: int default: 4096 diff --git a/src/client/msgr_rdma.cpp b/src/client/msgr_rdma.cpp index 78e3321c..a117cc06 100644 --- a/src/client/msgr_rdma.cpp +++ b/src/client/msgr_rdma.cpp @@ -131,6 +131,7 @@ static matched_dev match_device(ibv_device **dev_list, addr_mask_t *networks, in ibv_port_attr portinfo; ibv_gid_entry best_gidx; int res; + bool have_non_roce = false, have_roce = false; for (int i = 0; dev_list[i]; ++i) { auto dev = dev_list[i]; @@ -161,6 +162,11 @@ static matched_dev match_device(ibv_device **dev_list, addr_mask_t *networks, in else break; } + if (gidx.gid_type != IBV_GID_TYPE_ROCE_V1 && + gidx.gid_type != IBV_GID_TYPE_ROCE_V2) + have_non_roce = true; + else + have_roce = true; if (match_gid(&gidx, networks, nnet)) { // Prefer RoCEv2 @@ -186,6 +192,10 @@ cleanup: { log_rdma_dev_port_gid(dev_list[best.dev], best.port, best.gid, best_gidx); } + if (best.dev < 0 && have_non_roce && !have_roce) + { + best.dev = -2; + } return best; } @@ -237,11 +247,17 @@ msgr_rdma_context_t *msgr_rdma_context_t::create(std::vector osd_ne nets.push_back(cidr_parse(netstr)); } auto best = match_device(dev_list, nets.data(), nets.size(), log_level); - if (best.dev < 0) + if (best.dev == -2) + { + best.dev = 0; + if (log_level > 0) + fprintf(stderr, "No RoCE devices found, using first available RDMA device %s\n", ibv_get_device_name(*dev_list)); + } + else if (best.dev < 0) { if (log_level > 0) - fprintf(stderr, "RDMA device matching osd_network is not found, using first available device\n"); - best.dev = 0; + fprintf(stderr, "RDMA device matching osd_network is not found, disabling RDMA\n"); + goto cleanup; } else { @@ -301,10 +317,11 @@ msgr_rdma_context_t *msgr_rdma_context_t::create(std::vector osd_ne { continue; } - // Prefer IPv4 RoCEv2 GID by default + // Prefer IPv4 RoCEv2 -> IPv6 RoCEv2 -> IPv4 RoCEv1 -> IPv6 RoCEv1 -> IB if (gid_index == -1 || - gidx.gid_type == IBV_GID_TYPE_ROCE_V2 && - (ctx->my_gid.gid_type != IBV_GID_TYPE_ROCE_V2 || is_ipv4_gid(&gidx))) + gidx.gid_type == IBV_GID_TYPE_ROCE_V2 && ctx->my_gid.gid_type != IBV_GID_TYPE_ROCE_V2 || + gidx.gid_type == IBV_GID_TYPE_ROCE_V1 && ctx->my_gid.gid_type == IBV_GID_TYPE_IB || + gidx.gid_type == ctx->my_gid.gid_type && is_ipv4_gid(&gidx)) { gid_index = k; ctx->my_gid = gidx;