Как не застрять в rdma_get_recv_comp() или __ibv_get_cq_event()?

Товарищи хакеры RDMA, кто-нибудь знает, истекает ли время ожидания rdma_get_recv_comp(), которое вызывает __ibv_get_cq_event()?

Моя проблема связана с теми же программами, которые показаны здесь: Программа RDMA случайным образом зависает

Он работает нормально, но не устойчив к случайным отключениям клиентов. В частности, если я принудительно убью клиента, сервер застрянет в rdma_get_recv_comp() / ipv_get_cq_event().

Это для Mellanox ConnectX-3, и я проверил, что тайм-аут по умолчанию составляет 2,14 с, а повторные попытки = 1. Но мне не ясно, будет ли ibv_get_cq_event() в режиме блокировки даже тайм-аут. Объяснение тайм-аута в документации ibv_modify_qp() предполагает, что тайм-ауты применяются только для отправки (rdma_get_send_comp()), поскольку только отправители ждут ACK. Но я не вижу никаких трудностей в том, чтобы позволить приемам также иметь тайм-аут.

Если в этом случае ожидается зависание внутри rdma_get_recv_comp(), как я могу избежать этого или реализовать тайм-аут?

Некоторые возможности:

  1. изменить последовательность выключения моего клиента, чтобы он выполнял все необходимые отправки, чтобы он не оставлял rdma_get_recv_comp() на сервере висящим?

  2. замените rdma_get_recv_comp() циклом, который опрашивает завершение получения


person Yale Zhang    schedule 30.06.2016    source источник


Ответы (1)


ibv_get_cq_event() не истекает. Он ожидает событий завершения (которые генерируются, когда рабочий запрос завершается и создает запись в очереди завершения). Если событие не генерируется, скажем, из-за того, что ваш прием никогда не завершается, вы будете ждать вечно. Если QP (соединение) переходит в состояние ошибки, то все полученные сообщения будут завершены со статусом сброса, но если вы уничтожите QP до опроса всех завершений, они будут удалены из CQ.

Таким образом, ваша проблема может заключаться в том, что когда клиент отключается, другая сторона не обязательно обнаруживает отключение — например, если клиент просто перезагружается, тогда RDMA CM не отключится корректно, и если на стороне сервера нет отправки в полете он не заметит отключения. Вы можете справиться с этим с помощью своего рода поддержки активности — 0-байтовые RDMA WRITE хорошо подходят для этого, поскольку они являются NOP, но не будут работать, если что-то пойдет не так с соединением.

Или может случиться так, что ваш сервер слишком стремится уничтожить QP, когда он получает уведомление об отключении от RDMA CM. Вы хотите иметь счетчик ссылок в своей структуре соединения, чтобы ждать всего, чего вы собираетесь ждать, прежде чем уничтожить QP.

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

person Roland    schedule 01.07.2016