Skip to content

[BugFix] RDMA: retry ibv_post_send from bad_wr and drain CQ on failure - #8091

Merged
Sunny-bot1 merged 2 commits into
PaddlePaddle:developfrom
Sunny-bot1:fix_rdma_retry
Jul 2, 2026
Merged

[BugFix] RDMA: retry ibv_post_send from bad_wr and drain CQ on failure#8091
Sunny-bot1 merged 2 commits into
PaddlePaddle:developfrom
Sunny-bot1:fix_rdma_retry

Conversation

@Sunny-bot1

@Sunny-bot1 Sunny-bot1 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Motivation

生产环境中 KV Cache RDMA 传输时出现报错:

                                                                                                                                                                                                                               
  KV_CACHE ERROR ibv_post_send failed: File name too long (errno: 36), retry 7/7          
  KV_CACHE ERROR ibv_post_send failed after 7 retries: File name too long (errno: 36)      

errno 36 (ENAMETOOLONG) 在 RDMA 上下文中表示 ibv_post_send 向 Send Queue(SQ)提交 Work Request(WR)失败,根本原因是 SQ 堆积——inflight WR 累积速度超过 CQ 消费速度,导致 SQ 无可用 slot。

原有重试逻辑存在两个问题:

  1. 每次重试都从 WR 链表头部重新提交,而不是从 bad_wr 续传,导致已成功入队的 WR 被重复提交,每次 retry 反而进一步加剧 SQ 压力。
  2. retry 前没有排空 CQ,已完成的 WR 占用的 SQ slot 得不到释放,7 次重试全部因同一原因失败。

Modifications

kvcache_rdma.cpp — post_send_with_retry

  • 引入 cur_wr 指针初始化为 wr_list,失败时将其推进到 bad_wr,下次重试从第一个失败的 WR 开始,不重复提交已入队的 WR。
  • 每次 retry 前调用 poll_cq_with_timeout 主动排空 CQ,释放 SQ slot。

为什么不用 poll_cq_with_timeout:
ibv_post_send 失败并不保证 CQ 里有可消费的 CQE(如参数/QP 状态类同步错误,或 bad_wr 之前的 WR 均为无信号 WR 尚未产生 completion)。使用 30s 超时的阻塞式 poll 会导致每次 retry 卡住最长 30s,7 次重试共阻塞最多 210 秒。

修改前后对比

  // 修改前
  do {
      ret = ibv_post_send(ctx->qp, wr_list, &bad_wr);  // 始终从链表头重试
      if (ret != 0) {
          usleep(1000);
          retries++;
      }
  } while (retries < max_retries);

  // 修改后
  struct ibv_send_wr* cur_wr = wr_list;
  do {
      ret = ibv_post_send(ctx->qp, cur_wr, &bad_wr);
      if (ret != 0) {
          // 非阻塞排空 CQ,释放 SQ slot,不阻塞等待 CQE
          struct ibv_wc wc_array[32];
          int n;
          while ((n = ibv_poll_cq(ctx->cq, 32, wc_array)) > 0) {}
          usleep(1000);
          retries++;
          if (bad_wr) cur_wr = bad_wr;  // 从失败的 WR 续传
      }
  } while (retries < max_retries);

Usage or Command

Accuracy Tests

Checklist

  • Add at least a tag in the PR title.
    • Tag list: [[FDConfig],[APIServer],[Engine], [Scheduler], [PD Disaggregation], [Executor], [Graph Optimization], [Speculative Decoding], [RL], [Models], [Quantization], [Loader], [OP], [KVCache], [DataProcessor], [BugFix], [Docs], [CI], [Optimization], [Feature], [Benchmark], [Others], [XPU], [HPU], [GCU], [DCU], [Iluvatar], [Metax]]
    • You can add new tags based on the PR content, but the semantics must be clear.
  • Format your code, run pre-commit before commit.
  • Add unit tests. Please write the reason in this PR if no unit tests.
  • Provide accuracy results.
  • If the current PR is submitting to the release branch, make sure the PR has been submitted to the develop branch, then cherry-pick it to the release branch with the [Cherry-Pick] PR tag.

@Sunny-bot1 Sunny-bot1 changed the title fix rdma retry [BugFix] RDMA: retry ibv_post_send from bad_wr and drain CQ on failure Jul 2, 2026
PaddlePaddle-bot

This comment was marked as outdated.

@codecov-commenter

codecov-commenter commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (develop@7a60f79). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #8091   +/-   ##
==========================================
  Coverage           ?   67.51%           
==========================================
  Files              ?      475           
  Lines              ?    66915           
  Branches           ?    10321           
==========================================
  Hits               ?    45178           
  Misses             ?    18865           
  Partials           ?     2872           
Flag Coverage Δ
GPU 77.53% <ø> (?)
XPU 6.95% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@PaddlePaddle-bot PaddlePaddle-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Paddle-CI-Agent | pr_review | 2026-07-02 11:54:02

📋 Review 摘要

PR 概述:修复 RDMA KV Cache ibv_post_send 失败后的重试位置和 CQ drain 逻辑
变更范围fastdeploy/cache_manager/transfer_factory/kvcache_transfer/src/kvcache_rdma.cpp
影响面 Tag[KVCache] [PD Disaggregation]

问题

级别 文件 概述
🔴 Bug fastdeploy/cache_manager/transfer_factory/kvcache_transfer/src/kvcache_rdma.cpp:1544 retry 时无归属地 drain 共享 CQ,可能消费其它发送路径等待的 CQE

历史 Findings 修复情况

Finding 问题 状态
F1 失败后使用 poll_cq_with_timeout 导致每次 retry 最多阻塞 30 秒 ✅ 已修复

📝 PR 规范检查

标题符合 [BugFix] Tag 规范。描述包含必填章节,但 Usage or CommandAccuracy Tests 未填写有效内容,Checklist 未按当前 PR 情况勾选;可直接使用以下完整描述:

PR 描述建议(点击展开,可直接复制)
## Motivation
生产环境中 KV Cache RDMA 传输出现间歇性 `ibv_post_send` 失败,错误为 `errno=36 (ENAMETOOLONG)`。该问题与 Send Queue 中 inflight WR 堆积、CQ 未及时消费有关,原重试逻辑会从 WR 链表头重新提交,可能重复提交已成功入队的 WR。

## Modifications
- `fastdeploy/cache_manager/transfer_factory/kvcache_transfer/src/kvcache_rdma.cpp`: 在 `post_send_with_retry` 中引入 `cur_wr`,失败后从 `bad_wr` 指向的第一个失败 WR 继续重试。
- 在重试前尝试 poll CQ,以释放已完成 WR 对应的 SQ slot。

## Usage or Command
N/A

## Accuracy Tests
N/A。本 PR 修改 RDMA KV Cache 传输失败重试路径,不改变模型计算逻辑或输出精度。

## Checklist

- [x] Add at least a tag in the PR title.
  - Tag list: [`[FDConfig]`,`[APIServer]`,`[Engine]`, `[Scheduler]`, `[PD Disaggregation]`, `[Executor]`, `[Graph Optimization]`, `[Speculative Decoding]`, `[RL]`, `[Models]`, `[Quantization]`, `[Loader]`, `[OP]`, `[KVCache]`, `[DataProcessor]`, `[BugFix]`, `[Docs]`, `[CI]`, `[Optimization]`, `[Feature]`, `[Benchmark]`, `[Others]`, `[XPU]`, `[HPU]`, `[GCU]`, `[DCU]`, `[Iluvatar]`, `[Metax]`]
  - You can add new tags based on the PR content, but the semantics must be clear.
- [ ] Format your code, run `pre-commit` before commit.
- [ ] Add unit tests. Please write the reason in this PR if no unit tests.
- [x] Provide accuracy results.
- [x] If the current PR is submitting to the `release` branch, make sure the PR has been submitted to the `develop` branch, then cherry-pick it to the `release` branch with the `[Cherry-Pick]` PR tag.

总体评价

当前修改解决了历史 review 中指出的阻塞式 retry 问题,但新增的 CQ drain 需要先避免跨调用消费 completion,否则并发 KV 传输下仍可能出现超时或误判失败。

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 聚焦于修复生产环境 KV Cache RDMA 写入时 ibv_post_send 在 SQ 堆积场景下的重试失效问题,通过“从 bad_wr 续传”避免重复提交已入队 WR,并在失败重试前进行非阻塞 CQ drain 来尝试释放 SQ slot,从而提升在压力场景下的成功率与可恢复性。

Changes:

  • post_send_with_retry 中引入 cur_wr,失败后从 bad_wr 指向的 WR 继续重试,避免从链表头重复提交。
  • ibv_post_send 失败时增加非阻塞 ibv_poll_cq 循环 drain CQ,尝试释放 SQ slot 后再 retry。
  • 增加注释解释为何不使用阻塞式 poll_cq_with_timeout 来 drain。

Comment on lines +1516 to 1519
struct ibv_send_wr* cur_wr = wr_list;
do {
ret = ibv_post_send(ctx->qp, wr_list, &bad_wr);
ret = ibv_post_send(ctx->qp, cur_wr, &bad_wr);
if (ret == 0) {
Comment on lines +1541 to +1546
{
struct ibv_wc wc_array[32];
int n;
while ((n = ibv_poll_cq(ctx->cq, 32, wc_array)) > 0) {
}
}
@Sunny-bot1
Sunny-bot1 merged commit b4e7104 into PaddlePaddle:develop Jul 2, 2026
41 of 44 checks passed
@EmmonsCurse

Copy link
Copy Markdown
Collaborator

✅ Cherry-pick successful! Created PR: #8093

Sunny-bot1 added a commit that referenced this pull request Jul 2, 2026
#8091) (#8093)

* fix rdma retry

* fix

Co-authored-by: sunxin <68891411+Sunny-bot1@users.noreply.github.com>
@paddle-bot

paddle-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

Thanks for your contribution!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants