[object Object]

← back to Exo

Fix Thunderbolt bridge cycle detection to include 2-node cycles (#1261)

8a595fee2ff622d0b1ad7b5b5f415ba221af96f9 · 2026-01-23 19:34:48 +0000 · Alex Cheema

## Motivation

Packet storms occur with Thunderbolt bridge enabled on 2 machines
connected by Thunderbolt, not just 3+ node cycles as previously assumed.
The cycle detection was too conservative and missed this case.

## Changes

- Changed the minimum cycle length from >2 (3+ nodes) to >=2 (2+ nodes)
- Updated the early return threshold from `< 3` to `< 2` enabled nodes
- Updated docstring to reflect the new behavior

## Why It Works

A Thunderbolt bridge loop between just 2 machines can still create
broadcast storms when both have the bridge enabled. The previous
threshold of 3+ was based on an incorrect assumption that 2-node
connections wouldn't cause this problem.

## Test Plan

### Manual Testing
<!-- Hardware: (e.g., MacBook Pro M1 Max 32GB, Mac Mini M2 16GB,
connected via Thunderbolt 4) -->
- Tested with 2 machines connected via Thunderbolt with bridge enabled
- Confirmed packet storms occur in this configuration
- Verified the fix correctly detects and handles 2-node cycles

### Automated Testing
- Existing topology tests cover cycle detection logic

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

Files touched

Diff

commit 8a595fee2ff622d0b1ad7b5b5f415ba221af96f9
Author: Alex Cheema <41707476+AlexCheema@users.noreply.github.com>
Date:   Fri Jan 23 19:34:48 2026 +0000

    Fix Thunderbolt bridge cycle detection to include 2-node cycles (#1261)
    
    ## Motivation
    
    Packet storms occur with Thunderbolt bridge enabled on 2 machines
    connected by Thunderbolt, not just 3+ node cycles as previously assumed.
    The cycle detection was too conservative and missed this case.
    
    ## Changes
    
    - Changed the minimum cycle length from >2 (3+ nodes) to >=2 (2+ nodes)
    - Updated the early return threshold from `< 3` to `< 2` enabled nodes
    - Updated docstring to reflect the new behavior
    
    ## Why It Works
    
    A Thunderbolt bridge loop between just 2 machines can still create
    broadcast storms when both have the bridge enabled. The previous
    threshold of 3+ was based on an incorrect assumption that 2-node
    connections wouldn't cause this problem.
    
    ## Test Plan
    
    ### Manual Testing
    <!-- Hardware: (e.g., MacBook Pro M1 Max 32GB, Mac Mini M2 16GB,
    connected via Thunderbolt 4) -->
    - Tested with 2 machines connected via Thunderbolt with bridge enabled
    - Confirmed packet storms occur in this configuration
    - Verified the fix correctly detects and handles 2-node cycles
    
    ### Automated Testing
    - Existing topology tests cover cycle detection logic
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
---
 src/exo/shared/topology.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/exo/shared/topology.py b/src/exo/shared/topology.py
index 8baadfba..9d649a6f 100644
--- a/src/exo/shared/topology.py
+++ b/src/exo/shared/topology.py
@@ -248,8 +248,8 @@ class Topology:
     ) -> list[list[NodeId]]:
         """
         Find cycles in the Thunderbolt topology where all nodes have TB bridge enabled.
-        Only returns cycles with >2 nodes (3+ machines in a loop), as cycles with
-        2 or fewer nodes don't cause the broadcast storm problem.
+        Only returns cycles with >=2 nodes (2+ machines in a loop), as
+        1 node doesn't cause the broadcast storm problem.
         """
         enabled_nodes = {
             node_id
@@ -257,7 +257,7 @@ class Topology:
             if status.enabled
         }
 
-        if len(enabled_nodes) < 3:
+        if len(enabled_nodes) < 2:
             return []
 
         thunderbolt_ips = _get_ips_with_interface_type(
@@ -288,7 +288,7 @@ class Topology:
         return [
             [graph[idx] for idx in cycle]
             for cycle in rx.simple_cycles(graph)
-            if len(cycle) > 2
+            if len(cycle) >= 2
         ]
 
 

← c8571a17 Fix guidance (#1264)  ·  back to Exo  ·  Fix placement filter to use subset matching instead of exact d229df38 →