Skip to content

perf(nvlink-manager): process partition monitor groups concurrently - #4695

Open
rtamma-nv wants to merge 6 commits into
NVIDIA:mainfrom
rtamma-nv:feat/nvlink_optimization
Open

perf(nvlink-manager): process partition monitor groups concurrently#4695
rtamma-nv wants to merge 6 commits into
NVIDIA:mainfrom
rtamma-nv:feat/nvlink_optimization

Conversation

@rtamma-nv

Copy link
Copy Markdown
Contributor

Nvlink partition monitor currently works by fetching all MNNVL capable managed hosts, groups them by rack/cluster_chassis_serial and works on each group serially.
For sites with a large number of managed hosts, each iteration of partition monitor incurs significant memory footprint, latency, and DB query load.
Need to parallelize and optimize nvlink partition monitor handling to work at scale.

  • Batch chassis NMX-C endpoint lookups instead of one query per chassis serial
  • Pre-split machine_nvlink_info into per-group disjoint shards before the concurrent fan-out; groups are mutually exclusive so no locking is needed
  • Add a configurable concurreny limit (default 16)

Related issues

#4279

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • [ X] Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • [ X] Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

- Batch chassis NMX-C endpoint lookups instead of one query per chassis serial
- Pre-split machine_nvlink_info into per-group disjoint shards before
  the concurrent fan-out; groups are mutually exclusive so no locking
  is needed
- Add a configurable concurreny limit (default 16)
Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>

Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>
@rtamma-nv
rtamma-nv requested a review from a team as a code owner August 7, 2026 05:38
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary by CodeRabbit

  • New Features

    • Added configurable concurrency limits for processing NVLink machine groups, defaulting to 16.
    • NVLink monitoring now processes multiple machine groups concurrently while preserving bounded resource usage.
    • Added batched chassis endpoint lookup and consolidated monitoring metrics across groups.
  • Bug Fixes

    • Invalid zero-value concurrency settings are now rejected.
    • Monitoring results preserve failure reasons and partial observations during processing.

Walkthrough

The NVLink monitor now performs batched endpoint lookup and bounded concurrent machine-group processing. Group-local results and metrics are merged after processing. Configuration sets a non-zero concurrency limit with a default of 16.

Changes

NVLink monitor concurrency

Layer / File(s) Summary
Batch endpoint lookup and concurrency configuration
crates/api-db/src/nvlink_nmxc_endpoints.rs, crates/nvlink-manager/src/config.rs, crates/api-core/src/cfg/README.md
The database adds chassis-serial batch lookup. NvLinkConfig adds a non-zero concurrency limit, defaults it to 16, and rejects zero during deserialization.
Group result and metric aggregation
crates/nvlink-manager/src/lib.rs, crates/nvlink-manager/src/metrics.rs
Group processing returns completed operations, null observations, and partial metrics. merge_from combines counters, collections, health maps, duration samples, and non-empty metadata while preserving caller-owned fields.
Group execution and failure handling
crates/nvlink-manager/src/lib.rs
Group processing stores metrics and failure observations locally. Shared early-return handling preserves failure reasons and passes group-local state to reconciliation.
Bounded concurrent monitor iteration
crates/nvlink-manager/Cargo.toml, crates/nvlink-manager/src/lib.rs
The monitor creates disjoint group inputs, limits processing with a semaphore, performs batched endpoint resolution, and merges concurrent results. Tests cover result fan-in and aggregation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MonitorIteration
  participant NvlinkNmxcEndpoints
  participant ProcessMachineGroupInput
  participant NvlPartitionMonitorMetrics
  MonitorIteration->>NvlinkNmxcEndpoints: find_by_chassis_serials(chassis_serials)
  NvlinkNmxcEndpoints-->>MonitorIteration: matching endpoint rows
  MonitorIteration->>ProcessMachineGroupInput: process owned group input under semaphore limit
  ProcessMachineGroupInput-->>MonitorIteration: GroupResult
  MonitorIteration->>NvlPartitionMonitorMetrics: merge_from(group metrics)
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: concurrent processing of NVLink partition monitor groups.
Description check ✅ Passed The description accurately covers concurrent processing, batched lookups, the concurrency limit, and related testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/nvlink-manager/src/lib.rs (1)

1630-1668: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Every group repeats the same global logical-partition cleanup, now concurrently.

db_nvl_logical_partitions is the complete, iteration-wide list. Lines 1374 and 1400 pass that same list to every group input, and Line 1636 forwards it into CheckPartitionsInput. update_db_with_nmx_c_operations then walks the full list and calls db::nvl_logical_partition::final_delete for each partition marked as deleted.

Before this change the groups ran sequentially, so the first group deleted the rows and later groups deleted nothing. Now up to partition_monitor_max_concurrent_groups transactions issue the identical DELETE for the same rows at the same time. At best this is duplicated work plus row-lock contention. If final_delete touches several tables, the concurrent transactions can also acquire locks in different orders and deadlock, which would fail an otherwise healthy group.

Perform the deleted-logical-partition cleanup once per iteration in run_single_iteration_inner, after the fan-in, instead of once per group.

#!/bin/bash
# Description: Inspect final_delete for logical partitions and any cascading writes.
set -euo pipefail

fd -t f 'nvl_logical_partition.rs' crates/api-db --exec cat -n {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/lib.rs` around lines 1630 - 1668, Move deleted
logical-partition cleanup out of per-group processing and perform it once per
iteration in run_single_iteration_inner after all groups have been joined. Stop
passing the complete db_nvl_logical_partitions list through each
CheckPartitionsInput and remove its per-group handling from
update_db_with_nmx_c_operations, then invoke the existing final_delete flow once
using the iteration-wide list.
🧹 Nitpick comments (4)
crates/api-db/src/nvlink_nmxc_endpoints.rs (1)

110-168: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a table for the three find_by_chassis_serials tests.

The three tests invoke the same operation with different serial inputs and expectations. A single fixture plus a table of (input_serials, expected_serials) cases would reduce duplication and keep one database round of setup. Keep the standalone form if per-case row seeding must differ.

As per coding guidelines: "Use a table whenever two or more tests invoke the same operation with different inputs, but keep genuinely distinct tests standalone."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-db/src/nvlink_nmxc_endpoints.rs` around lines 110 - 168,
Consolidate the three find_by_chassis_serials tests into one table-driven test
with shared fixture rows and cases containing input serials and expected
serials. Iterate over each case and assert the returned results, preserving the
empty-input and unknown-serial behaviors; keep separate setup only if a case
genuinely requires different seeded rows.

Source: Coding guidelines

crates/nvlink-manager/src/lib.rs (3)

3837-3851: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

The test re-implements the production fan-in instead of exercising it.

The comment states that the block mirrors the fold in run_single_iteration_inner. The test therefore validates a copy of the logic, not the logic itself. If the production fold changes, this test still passes.

Extract the fold into a small function, for example fn fold_group_results(metrics: &mut NvlPartitionMonitorMetrics, results: Vec<GroupResult>) -> (usize, Vec<PendingNullNvlinkObservation>), and call it from both run_single_iteration_inner and this test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/lib.rs` around lines 3837 - 3851, Extract the
duplicated group-result fan-in logic from `run_single_iteration_inner` and this
test into a shared helper such as `fold_group_results`, returning the
completed-operation count and pending null observations while updating
`NvlPartitionMonitorMetrics`. Replace both existing folds with calls to this
helper, preserving the current metric initialization and merge behavior.

1471-1486: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the early_return! macro with an explicit helper.

The macro expands to a return from the enclosing function. This hides control flow from the reader and from tooling. A small associated function that builds the failure GroupResult keeps the control flow explicit at each call site while removing the same duplication.

♻️ Proposed refactor
-        macro_rules! early_return {
-            ($reason:expr) => {{
-                Self::queue_null_nvlink_status_observation(
-                    &mut null_observations,
-                    &group_id,
-                    group_type,
-                    snapshots,
-                    $reason,
-                );
-                return GroupResult {
-                    completed_operations: 0,
-                    null_observations,
-                    partial_metrics: group_metrics,
-                };
-            }};
-        }
+        // Builds the terminal `GroupResult` for a group that cannot reach NMX-C.
+        let unreachable = |mut null_observations: Vec<PendingNullNvlinkObservation>,
+                           group_metrics: NvlPartitionMonitorMetrics,
+                           reason: ChassisNmxCUnreachableReason| {
+            Self::queue_null_nvlink_status_observation(
+                &mut null_observations,
+                &group_id,
+                group_type,
+                snapshots,
+                reason,
+            );
+            GroupResult {
+                completed_operations: 0,
+                null_observations,
+                partial_metrics: group_metrics,
+            }
+        };

Each site then reads return unreachable(null_observations, group_metrics, ChassisNmxCUnreachableReason::NoEndpoint);.

As per coding guidelines: "Prefer simple, explicit Rust code over clever or heavily abstracted code; add abstractions only for real requirements."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/lib.rs` around lines 1471 - 1486, Replace the
early_return! macro with a small associated helper that records the null NVLink
status observation and constructs the failure GroupResult without performing the
return itself. Update every macro call site to explicitly return the helper’s
result, preserving the existing completed_operations, null_observations, and
partial_metrics values and each call’s reason.

Source: Coding guidelines


1404-1419: 🚀 Performance & Scalability | 🔵 Trivial

Reserve database pool capacity for the partition monitor.

max_database_connections defaults to 1000 and is 64 in development, while the monitor limit independently defaults to 16. The group transactions run sequentially, so each active group uses at most one connection from these operations. If an operator sets the pool below 16, the monitor can still consume the entire pool. Document and validate a limit that reserves connections for other components.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/lib.rs` around lines 1404 - 1419, Document and
validate the relationship between max_database_connections and
partition_monitor_max_concurrent_groups so the monitor cannot consume the entire
database pool. Require enough reserved capacity for other components, rejecting
invalid configuration during startup while preserving the existing
semaphore-based group processing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/nvlink-manager/src/config.rs`:
- Around line 57-72: Prevent zero from reaching the partition monitor semaphore:
update NvLinkConfig::partition_monitor_max_concurrent_groups to use a non-zero
representation and adjust serde defaults accordingly, then pass its validated
value via get() when constructing the semaphore in run_single_iteration_inner.
Preserve the default of 16 and ensure deserialization rejects or otherwise
cannot produce zero.

In `@crates/nvlink-manager/src/metrics.rs`:
- Line 304: Update the release notes to document that
carbide_nvlink_partition_monitor_machine_status_updates_count now reports the
total machine NVLink status updates across all groups per iteration, rather than
the final group’s count. Confirm that existing dashboards and alert thresholds
account for the increased multi-group values.

---

Outside diff comments:
In `@crates/nvlink-manager/src/lib.rs`:
- Around line 1630-1668: Move deleted logical-partition cleanup out of per-group
processing and perform it once per iteration in run_single_iteration_inner after
all groups have been joined. Stop passing the complete db_nvl_logical_partitions
list through each CheckPartitionsInput and remove its per-group handling from
update_db_with_nmx_c_operations, then invoke the existing final_delete flow once
using the iteration-wide list.

---

Nitpick comments:
In `@crates/api-db/src/nvlink_nmxc_endpoints.rs`:
- Around line 110-168: Consolidate the three find_by_chassis_serials tests into
one table-driven test with shared fixture rows and cases containing input
serials and expected serials. Iterate over each case and assert the returned
results, preserving the empty-input and unknown-serial behaviors; keep separate
setup only if a case genuinely requires different seeded rows.

In `@crates/nvlink-manager/src/lib.rs`:
- Around line 3837-3851: Extract the duplicated group-result fan-in logic from
`run_single_iteration_inner` and this test into a shared helper such as
`fold_group_results`, returning the completed-operation count and pending null
observations while updating `NvlPartitionMonitorMetrics`. Replace both existing
folds with calls to this helper, preserving the current metric initialization
and merge behavior.
- Around line 1471-1486: Replace the early_return! macro with a small associated
helper that records the null NVLink status observation and constructs the
failure GroupResult without performing the return itself. Update every macro
call site to explicitly return the helper’s result, preserving the existing
completed_operations, null_observations, and partial_metrics values and each
call’s reason.
- Around line 1404-1419: Document and validate the relationship between
max_database_connections and partition_monitor_max_concurrent_groups so the
monitor cannot consume the entire database pool. Require enough reserved
capacity for other components, rejecting invalid configuration during startup
while preserving the existing semaphore-based group processing.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 33e2b7d9-2112-4033-b577-af45726e117d

📥 Commits

Reviewing files that changed from the base of the PR and between 9d296f6 and 4e539a0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • crates/api-db/src/nvlink_nmxc_endpoints.rs
  • crates/nvlink-manager/Cargo.toml
  • crates/nvlink-manager/src/config.rs
  • crates/nvlink-manager/src/lib.rs
  • crates/nvlink-manager/src/metrics.rs
  • crates/nvlink-manager/src/nmx_c_endpoint.rs
💤 Files with no reviewable changes (1)
  • crates/nvlink-manager/src/nmx_c_endpoint.rs

Comment thread crates/nvlink-manager/src/config.rs
Comment thread crates/nvlink-manager/src/metrics.rs
…r_mzx_concurrent_groups

Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (3)
crates/nvlink-manager/src/config.rs (3)

70-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the default helper’s visibility.

default_partition_monitor_max_concurrent_groups has no external callers. Change pub const fn to const fn; the serde default and local tests remain valid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/config.rs` at line 70, Change the visibility of
default_partition_monitor_max_concurrent_groups from pub const fn to const fn,
leaving its const behavior and existing serde default and local test usage
unchanged.

Source: Coding guidelines


71-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the unnecessary unsafe constructor.

NonZeroUsize::new(16).expect("16 is non-zero") is const-compatible with Rust 1.96.0 and preserves the invariant without an unsafe block.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/config.rs` around lines 71 - 72, Replace the unsafe
NonZeroUsize::new_unchecked(16) construction with the const-compatible safe
NonZeroUsize::new(16).expect(...) form, preserving the existing value and
invariant without an unsafe block.

Source: Coding guidelines


60-62: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Make the default helper private and remove the unnecessary unsafe construction. Only local configuration code and tests use default_partition_monitor_max_concurrent_groups; pub is not required. Use safe NonZeroUsize::new(16) construction. The semaphore consumer already calls .get().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/nvlink-manager/src/config.rs` around lines 60 - 62, Update
NvLinkConfig::default_partition_monitor_max_concurrent_groups to be private,
since it is only used locally and by tests. Replace its unsafe NonZeroUsize
construction with the safe NonZeroUsize::new(16) approach, preserving the
existing default value and semaphore consumer’s .get() usage.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/nvlink-manager/src/config.rs`:
- Line 70: Change the visibility of
default_partition_monitor_max_concurrent_groups from pub const fn to const fn,
leaving its const behavior and existing serde default and local test usage
unchanged.
- Around line 71-72: Replace the unsafe NonZeroUsize::new_unchecked(16)
construction with the const-compatible safe NonZeroUsize::new(16).expect(...)
form, preserving the existing value and invariant without an unsafe block.
- Around line 60-62: Update
NvLinkConfig::default_partition_monitor_max_concurrent_groups to be private,
since it is only used locally and by tests. Replace its unsafe NonZeroUsize
construction with the safe NonZeroUsize::new(16) approach, preserving the
existing default value and semaphore consumer’s .get() usage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e14a452c-dffc-45d5-a269-bad90a1ff81e

📥 Commits

Reviewing files that changed from the base of the PR and between 4e539a0 and 8324d4f.

📒 Files selected for processing (2)
  • crates/nvlink-manager/src/config.rs
  • crates/nvlink-manager/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/nvlink-manager/src/lib.rs

…to NvLinkConfig table

Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/api-core/src/cfg/README.md`:
- Line 353: Update the partition_monitor_max_concurrent_groups entry in the
README configuration table to explicitly document that omitted values default to
16, positive usize values are accepted, and 0 is rejected during configuration
deserialization; then inspect the generated admin-UI table to ensure the
corresponding documentation is updated consistently.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 47446d1e-9665-46a1-8ffe-5f3b01676610

📥 Commits

Reviewing files that changed from the base of the PR and between 8324d4f and d32eea5.

📒 Files selected for processing (1)
  • crates/api-core/src/cfg/README.md

Comment thread crates/api-core/src/cfg/README.md
@rtamma-nv rtamma-nv closed this Aug 7, 2026
Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>
@rtamma-nv rtamma-nv reopened this Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions

Copy link
Copy Markdown

Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>
Signed-off-by: Roopesh Tamma <rtamma@nvidia.com>
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.

1 participant