Skip to content

fix error checking against IB verbs API (#2265)#3034

Merged
wwbmmm merged 2 commits intoapache:masterfrom
live4thee:rdma-2265
Aug 2, 2025
Merged

fix error checking against IB verbs API (#2265)#3034
wwbmmm merged 2 commits intoapache:masterfrom
live4thee:rdma-2265

Conversation

@live4thee
Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: #2265

Problem Summary:

现有的代码中对 IB verbs API 的使用有误。很多 API 的返回值本身是错误码(errno),但并不会修改 errno.

What is changed and the side effects?

Changed:

Side effects:

  • Performance effects:

  • Breaking backward compatibility:


Check List:

Signed-off-by: Qun, Li <qun.li@zstack.io>
@yanglimingcn
Copy link
Copy Markdown
Contributor

yanglimingcn commented Jul 21, 2025

LGTM
所以问题出现在“很多 API 的返回值本身是错误码(errno),但并不会修改 errno”这块吗?是CutFromIOBufList报错,errno没有设置导致的问题吗?

Comment thread src/brpc/rdma/rdma_helper.cpp Outdated
Comment thread src/brpc/rdma/rdma_helper.cpp Outdated
Comment thread src/brpc/rdma/rdma_helper.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
@chenBright chenBright linked an issue Jul 21, 2025 that may be closed by this pull request
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Comment thread src/brpc/rdma/rdma_endpoint.cpp
Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
@live4thee
Copy link
Copy Markdown
Contributor Author

LGTM 所以问题出现在“很多 API 的返回值本身是错误码(errno),但并不会修改 errno”这块吗?是CutFromIOBufList报错,errno没有设置导致的问题吗?

对。

@live4thee
Copy link
Copy Markdown
Contributor Author

@wwbmmm @chenBright 新推了一个 commit 解决评论中提出的建议。

@zhangqiongyu
Copy link
Copy Markdown
Contributor

解决了一直困扰我的一个日志问题

@yanglimingcn
Copy link
Copy Markdown
Contributor

使用这个PR后,会报这样的错误:
image
你们遇到过吗

@live4thee
Copy link
Copy Markdown
Contributor Author

使用这个PR后,会报这样的错误: image 你们遇到过吗

这其实是没有补丁之前被隐藏起来的问题,且导致数据错的地方。这个报错应该是 RDMA send queue 满了,可能滑动窗口逻辑未能很好工作。

@yanglimingcn
Copy link
Copy Markdown
Contributor

yanglimingcn commented Jul 22, 2025

看这个日志window还有不少空间,挺奇怪了。这个问题,你们那边这个pr用了之后没有遇到过是吗?

Comment thread src/brpc/rdma/rdma_endpoint.cpp Outdated
Signed-off-by: Qun, Li <qun.li@zstack.io>
@live4thee
Copy link
Copy Markdown
Contributor Author

@yanglimingcn @chenBright @Tuvie Comments? Concerns?

Comment thread src/brpc/rdma/rdma_endpoint.cpp
@yanglimingcn
Copy link
Copy Markdown
Contributor

LGTM

@wwbmmm wwbmmm merged commit f8c1dbc into apache:master Aug 2, 2025
15 checks passed
wwbmmm pushed a commit that referenced this pull request Aug 2, 2025
* fix error checking against IB verbs API (#2265)

Signed-off-by: Qun, Li <qun.li@zstack.io>

* style and log changes according to comments

Signed-off-by: Qun, Li <qun.li@zstack.io>

---------

Signed-off-by: Qun, Li <qun.li@zstack.io>
@live4thee live4thee deleted the rdma-2265 branch August 4, 2025 06:38
@sunce4t
Copy link
Copy Markdown

sunce4t commented Sep 29, 2025

使用这个PR后,会报这样的错误: image 你们遇到过吗

hi,这个能使用rdma performance复现出来吗? 我们也遇到了这个问题,但我没找到简单的复现方法,我个人猜测是 RDMA的SQ和RQ共享了CQ后,此时SQ和RQ之间生成CQE的顺序是不保证的,因此是否存在这样一种罕见情况: RQ收到对端的SendACK后生成的CQE 在 SQ的CQE之前,在PollCQ中处理时,1.先处理到RQ的CQE,增加window的值;2.再处理SQ的CQE;如果在1和2这两步之间有其他的线程发请求,检查到window的值非0,但此时由于还没poll到SQ的CQE,SQ中的指针没有更新,就导致无法发送成功。
想问下是否可以通过rdma performance复现出来?方便定位原因。

@live4thee
Copy link
Copy Markdown
Contributor Author

使用这个PR后,会报这样的错误: image 你们遇到过吗

hi,这个能使用rdma performance复现出来吗? 我们也遇到了这个问题,但我没找到简单的复现方法,我个人猜测是 RDMA的SQ和RQ共享了CQ后,此时SQ和RQ之间生成CQE的顺序是不保证的,因此是否存在这样一种罕见情况: RQ收到对端的SendACK后生成的CQE 在 SQ的CQE之前,在PollCQ中处理时,1.先处理到RQ的CQE,增加window的值;2.再处理SQ的CQE;如果在1和2这两步之间有其他的线程发请求,检查到window的值非0,但此时由于还没poll到SQ的CQE,SQ中的指针没有更新,就导致无法发送成功。 想问下是否可以通过rdma performance复现出来?方便定位原因。

具体是报什么错?图片好像显示不出来。

@sunce4t
Copy link
Copy Markdown

sunce4t commented Sep 30, 2025

使用这个PR后,会报这样的错误: image 你们遇到过吗

hi,这个能使用rdma performance复现出来吗? 我们也遇到了这个问题,但我没找到简单的复现方法,我个人猜测是 RDMA的SQ和RQ共享了CQ后,此时SQ和RQ之间生成CQE的顺序是不保证的,因此是否存在这样一种罕见情况: RQ收到对端的SendACK后生成的CQE 在 SQ的CQE之前,在PollCQ中处理时,1.先处理到RQ的CQE,增加window的值;2.再处理SQ的CQE;如果在1和2这两步之间有其他的线程发请求,检查到window的值非0,但此时由于还没poll到SQ的CQE,SQ中的指针没有更新,就导致无法发送成功。 想问下是否可以通过rdma performance复现出来?方便定位原因。

具体是报什么错?图片好像显示不出来。

[PS2][W][0928 22:13:48.368256][20670][rdma_endpoint.cpp:878] Fail to ibv_post_send: Cannot allocate memory, window=7, sq_current=1
[PS2][W][0928 22:13:48.368309][20670][socket.cpp:1781] Fail to keep-write into Socket{id=5989 fd=1126 addr=10.24.31.213:14240:3422} (0x7fac8189d900): Cannot allocate memory [12]

@live4thee
Copy link
Copy Markdown
Contributor Author

使用这个PR后,会报这样的错误: image 你们遇到过吗

hi,这个能使用rdma performance复现出来吗? 我们也遇到了这个问题,但我没找到简单的复现方法,我个人猜测是 RDMA的SQ和RQ共享了CQ后,此时SQ和RQ之间生成CQE的顺序是不保证的,因此是否存在这样一种罕见情况: RQ收到对端的SendACK后生成的CQE 在 SQ的CQE之前,在PollCQ中处理时,1.先处理到RQ的CQE,增加window的值;2.再处理SQ的CQE;如果在1和2这两步之间有其他的线程发请求,检查到window的值非0,但此时由于还没poll到SQ的CQE,SQ中的指针没有更新,就导致无法发送成功。 想问下是否可以通过rdma performance复现出来?方便定位原因。

具体是报什么错?图片好像显示不出来。

[PS2][W][0928 22:13:48.368256][20670][rdma_endpoint.cpp:878] Fail to ibv_post_send: Cannot allocate memory, window=7, sq_current=1 [PS2][W][0928 22:13:48.368309][20670][socket.cpp:1781] Fail to keep-write into Socket{id=5989 fd=1126 addr=10.24.31.213:14240:3422} (0x7fac8189d900): Cannot allocate memory [12]

前面 7/22 @yanglimingcn 也提到了这个现象。没有这个补丁时,由于这里 ENOMEM 未能捕获,导致数据错。可能还是滑动窗口逻辑的问题。也许指定更大的 attachment_size/thread_num/queue_depth 能复现?或者多个 client 压一个 server.

@sunce4t
Copy link
Copy Markdown

sunce4t commented Oct 8, 2025

使用这个PR后,会报这样的错误: image 你们遇到过吗

hi,这个能使用rdma performance复现出来吗? 我们也遇到了这个问题,但我没找到简单的复现方法,我个人猜测是 RDMA的SQ和RQ共享了CQ后,此时SQ和RQ之间生成CQE的顺序是不保证的,因此是否存在这样一种罕见情况: RQ收到对端的SendACK后生成的CQE 在 SQ的CQE之前,在PollCQ中处理时,1.先处理到RQ的CQE,增加window的值;2.再处理SQ的CQE;如果在1和2这两步之间有其他的线程发请求,检查到window的值非0,但此时由于还没poll到SQ的CQE,SQ中的指针没有更新,就导致无法发送成功。 想问下是否可以通过rdma performance复现出来?方便定位原因。

具体是报什么错?图片好像显示不出来。

[PS2][W][0928 22:13:48.368256][20670][rdma_endpoint.cpp:878] Fail to ibv_post_send: Cannot allocate memory, window=7, sq_current=1 [PS2][W][0928 22:13:48.368309][20670][socket.cpp:1781] Fail to keep-write into Socket{id=5989 fd=1126 addr=10.24.31.213:14240:3422} (0x7fac8189d900): Cannot allocate memory [12]

前面 7/22 @yanglimingcn 也提到了这个现象。没有这个补丁时,由于这里 ENOMEM 未能捕获,导致数据错。可能还是滑动窗口逻辑的问题。也许指定更大的 attachment_size/thread_num/queue_depth 能复现?或者多个 client 压一个 server.

hi @yanglimingcn ,想请教下,之前你是使用rdma performance测试程序遇到的这个错误吗,可以提供一下相应的参数吗

@yanglimingcn
Copy link
Copy Markdown
Contributor

yanglimingcn commented Oct 8, 2025

我们没有遇到,不过应该是有些人也遇到过,通过调整sq和rq的数量就解决了,我觉得问题和你描述的也有联系。
cq;
// NOTE: Since we hope to reduce send completion events, we set signaled
// send_wr every 1/4 of the total wnd. The wnd will increase when the ack
// is received, which means the receive side has already received the data
// in the corresponding send_wr. However, the ack does not mean the send_wr
// has been removed from SQ if it is set unsignaled. The reason is that
// the unsignaled send_wr is removed from SQ only after the CQE of next
// signaled send_wr is polled. Thus in a rare case, a new send_wr cannot be
// posted to SQ even in the wnd is not empty. In order to solve this
// problem, we enlarge the size of SQ to contain redundant 1/4 of the wnd,
// which is the maximum number of unsignaled send_wrs.
我认为这段注释大概描述了这个问题

@sunce4t
Copy link
Copy Markdown

sunce4t commented Oct 8, 2025

我们没有遇到,不过应该是有些人也遇到过,通过调整sq和rq的数量就解决了,我觉得问题和你描述的也有联系。 cq; // NOTE: Since we hope to reduce send completion events, we set signaled // send_wr every 1/4 of the total wnd. The wnd will increase when the ack // is received, which means the receive side has already received the data // in the corresponding send_wr. However, the ack does not mean the send_wr // has been removed from SQ if it is set unsignaled. The reason is that // the unsignaled send_wr is removed from SQ only after the CQE of next // signaled send_wr is polled. Thus in a rare case, a new send_wr cannot be // posted to SQ even in the wnd is not empty. In order to solve this // problem, we enlarge the size of SQ to contain redundant 1/4 of the wnd, // which is the maximum number of unsignaled send_wrs. 我认为这段注释大概描述了这个问题

attr.cap.max_send_wr = sq_size * 5 / 4; /NOTE/
我们之前没有调整任何参数,默认就是brpc的参数,然后遇到了这个问题。现在基本确认是cqe的序的问题。在将这几处
76e354c9e6e82e0fa9b22edf1aeaae84967a4d98

从 / 4 修改成 / 8,提高send cqe的生成频率,也会减少这个问题。

@yanglimingcn
Copy link
Copy Markdown
Contributor

yanglimingcn commented Oct 9, 2025

这个问题你这边如果能系统性的解决欢迎提出PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RDMA failure

6 participants