Skip to content

fix: correctly detect RDMA bandwidth for bonded NICs - #705

Open
cynton503 wants to merge 1 commit into
deepseek-ai:mainfrom
cynton503:fix/rdma-bond-speed-detection
Open

fix: correctly detect RDMA bandwidth for bonded NICs#705
cynton503 wants to merge 1 commit into
deepseek-ai:mainfrom
cynton503:fix/rdma-bond-speed-detection

Conversation

@cynton503

Copy link
Copy Markdown

Summary

Fix incorrect RDMA bandwidth detection for bonded NIC devices (e.g., mlx5_bond_*), which causes suboptimal SM allocation and reduced dispatch/combine throughput.

Problem

In RDMA LAG (bond) mode, ibstat reports only a single logical port with per-port rate:

CA 'mlx5_bond_7'
        CA type: MT4131
        Number of ports: 1
        Port 1:
                Rate: 400

The existing get_rdma_gbs() parses this single port rate and computes 400 / 8 = 50 GB/s. However, dual-port CX7/CX8 NICs in bond mode aggregate two 400 Gb/s physical ports, so the actual available bandwidth is 800 / 8 = 100 GB/s.

This under-reported bandwidth causes get_theoretical_num_sms() to recommend fewer SMs than optimal, directly reducing dispatch/combine kernel performance.

Changes

  • Add get_net_device_speed_gbs(): maps IB device to its network interface via sysfs (/sys/class/infiniband/<dev>/ports/<port>/gid_attrs/ndevs/0), then reads the kernel-reported aggregated link speed from /sys/class/net/<iface>/speed (in Mbps).
  • Update get_rdma_gbs() with a three-level detection priority:
    1. EP_OVERRIDE_RDMA_GBS environment variable — manual override, consistent with EP_OVERRIDE_RDMA_SL convention
    2. sysfs aggregated speed — for bond devices (NIC name containing bond)
    3. ibstat Rate parsing — original fallback for non-bond devices or when sysfs is unavailable

Validation

Verified on a multi-node cluster with CX8 dual-port NICs in RDMA LAG mode (EP_NIC_NAME=mlx5_bond_0):

Config QP / SM (before) QP / SM (after) Dispatch GB/s (before → after) Combine GB/s (before → after)
2-node 65 / 12 65 / 22 49 → 58 53 → 79
4-node 65 / 6 65 / 10 53 → 77 53 → 81

Compatibility

  • Non-bond devices: behavior unchanged — the sysfs branch is skipped when NIC name does not contain bond
  • sysfs unavailable: silently falls back to ibstat parsing (returns 0 on any failure)
  • Manual override: EP_OVERRIDE_RDMA_GBS=<value_in_GBs> takes highest priority for any device type

For RDMA bond devices (e.g., mlx5_bond_*), ibstat only reports a single
logical port with per-port rate, missing the aggregated bandwidth of
multiple physical ports. This causes get_rdma_gbs() to return 50 GB/s
instead of the correct 100 GB/s on dual-port CX7/CX8 NICs in bond mode,
leading to suboptimal SM/QP allocation in get_theoretical_num_sms().

Fix by adding sysfs-based speed detection for bond devices:
- Map IB device to netdev via /sys/class/infiniband/<dev>/ports/<port>/gid_attrs/ndevs/0
- Read the kernel-reported aggregated speed from /sys/class/net/<iface>/speed
- Fall back to ibstat parsing if sysfs is unavailable

Also add EP_OVERRIDE_RDMA_GBS environment variable for manual override,
consistent with existing EP_OVERRIDE_RDMA_SL convention.
Comment thread deep_ep/utils/envs.py
nic_name: the NIC device name.

Returns:
gbs: the RDMA bandwidth in GB/s (0 if detection fails).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 warning: The new EP_OVERRIDE_RDMA_GBS environment variable is not documented in the README 'Networking' env var section, unlike its sibling EP_OVERRIDE_RDMA_SL (README.md:342). Since the PR explicitly frames this override as following the EP_OVERRIDE_RDMA_SL convention, please add a matching entry (e.g. 'EP_OVERRIDE_RDMA_GBS: float, override the detected RDMA bandwidth in GB/s') so operators can discover it.

🤖 v3

Comment thread deep_ep/utils/envs.py

speed_path = f'/sys/class/net/{net_iface}/speed'
with open(speed_path) as f:
speed_mbps = int(f.read().strip())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔵 suggestion: The broad except Exception: return 0 swallows all errors silently (unlike the ibstat branch which prints a diagnostic on failure). For a bond device where sysfs is expected to work, a silent fallback can mask misconfiguration and quietly re-introduce the under-reported bandwidth this PR is fixing. Consider a debug/warn log on the sysfs failure path to aid troubleshooting, while still falling back to ibstat.

🤖 v3

Comment thread deep_ep/utils/envs.py

return speed_mbps / 8000 if speed_mbps > 0 else 0
except Exception:
return 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔵 suggestion: Consider a brief inline comment on the speed_mbps / 8000 conversion (e.g. 'Mbps -> GB/s: /8 for bits->bytes, /1000 for M->G'). The 8000 magic number is non-obvious and easy to misread as a bug; it is in fact correct and consistent with the ibstat branch's rate/8.

🤖 v3

Comment thread deep_ep/utils/envs.py
# Environment variable override (highest priority)
if 'EP_OVERRIDE_RDMA_GBS' in os.environ:
return float(os.environ['EP_OVERRIDE_RDMA_GBS'])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔵 suggestion: The bond-detection heuristic uses substring match 'bond' in nic_name. This matches mlx5_bond_* naming and, combined with the safe 0/fallback behavior of get_net_device_speed_gbs(), preserves non-bond behavior as intended. Consider either attempting the sysfs path unconditionally (with ibstat as fallback) so other multi-port topologies also benefit, or adding a short comment explaining that the bond-only gating is an intentional compatibility guarantee.

🤖 v3

@ds-review-bot

Copy link
Copy Markdown
Collaborator

🤖 ds-review-bot Code Review

v6

The bonded-NIC sysfs lookup, unit conversion, fallback behavior, and explicit override are consistent with existing bandwidth detection semantics. No actionable regressions were identified.

v4

⚠️ 未完成评审(no_result_file:模型未产出结果文件)

v3

The change adds a sysfs-based RDMA bandwidth detection path to correctly report the aggregated link speed for bonded NICs (e.g. mlx5_bond_*), where ibstat only reports a single logical port's rate. A new helper get_net_device_speed_gbs() maps the IB device to its network interface via /sys/class/infiniband/<dev>/ports/<port>/gid_attrs/ndevs/0 and reads /sys/class/net/<iface>/speed (Mbps), and get_rdma_gbs() is updated with a three-level priority: EP_OVERRIDE_RDMA_GBS env override, sysfs aggregated speed for bond devices, then the original ibstat fallback. The implementation is well-scoped, defensive (returns 0 / falls back on any failure), and preserves behavior for non-bond devices. The unit conversion is correct and consistent with the ibstat branch (speed_mbps/8000 == rate/8 semantics; both decimal GB/s). Reading only the first port's aggregated bond netdev speed is correct and does not double-count. get_rdma_gbs remains lru_cache'd, so the env override / sysfs read happens once per nic_name per process, consistent with pre-existing behavior. The empirical validation table is convincing. Overall a solid, low-risk fix; the notable follow-ups are documenting the new env var and improving observability of the sysfs failure path.

Files reviewed: 1
Issues found: 🟡 1 warning | 🔵 3 suggestion
Inline comments posted: 4

⚠️ Parse warning: [v4] no_result_file:模型未产出结果文件

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.

2 participants