0

各位 RDMA 黑客,有谁知道调用 __ibv_get_cq_event() 的 rdma_get_recv_comp() 是否超时?

我的问题与此处显示的程序相同: 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()

4

1 回答 1

2

ibv_get_cq_event()不会超时。它等待完成事件(在工作请求完成并生成完成队列条目时生成)。如果没有生成事件,比如因为您的接收从未完成,那么您将永远等待。如果 QP(连接)转换为错误状态,则所有发布的接收都将以刷新状态完成 - 但如果您在轮询所有完成之前销毁 QP,那么它们将从 CQ 中删除。

所以你的问题可能是当客户端断开连接时,另一端不一定检测到断开连接 - 例如,如果客户端刚刚重新启动,那么 RDMA CM 不会完全断开连接,如果服务器端没有任何发送在飞行中,它不会注意到断开连接。您可以使用某种 keepalive 来处理这个问题——0 字节 RDMA WRITE 可以很好地解决这个问题,因为它们是 NOP,但如果连接出现任何问题,它们就会失败。

或者可能是您的服务器在收到来自 RDMA CM 的断开连接通知时太急于销毁 QP。您希望对您的连接结构有一个引用计数,以便在销毁 QP 之前等待您要等待的所有内容。

最后,可以以ibv_get_cq_event()非阻塞方式使用。手册页有一个使用poll()底层完成通道文件描述符来等待超时事件的示例。

于 2016-07-01T18:04:56.093 回答