Skip to content

[BUG] JACCL never detects a lost peer: survivors busy-wait at 100% CPU indefinitely #4278

Description

@erwinzhang7

What happens

When a rank stops responding, the other ranks of a JACCL group wait forever. No
timeout, no error, and not idly: each survivor spins a full core.

Four M4 Pro minis, full mesh over Thunderbolt RDMA, all four in a loop of 16 MB
all_sum inside try/except. Rank 2 suspended with SIGSTOP:

  • the other three froze at the same iteration and stayed there, silent, indefinitely
  • no exception, no abort, nothing on stderr
  • ps showed all three at 99 to 100% CPU in state Rs+, so they are busy-waiting
    rather than blocked on a descriptor
  • SIGCONT and all four resumed and completed normally, no corruption, no lost work

So a transient stall is survivable, which is good, and a death is indistinguishable
from it, which is not. Nothing ever reports that a peer is gone.

Why SIGSTOP rather than killing a rank

mlx.launch kills the surviving ranks the moment any rank exits, so it hides
whatever the survivors would have done. Suspending one rank leaves the process alive,
so the launcher stays out of the way while the peer stops servicing RDMA entirely.

Cutting the victim off at the network layer does not work as
a test: with ifconfig en2/en3/en4 down, the interfaces showing neither UP nor
RUNNING and IP ping over the point to point link at 100% loss, the four rank
collective kept running at full speed. RDMA over Thunderbolt does not go through
the IP stack once queue pairs are established. The /30 addresses only bootstrap the
side channel.

Comparison with ring

Ring had the same shape and it was addressed: #4060 made a lost peer fail the pending
tasks, and #3742 turns that into a catchable error. On the three revisions, a two
rank ring peer loss gives: v0.32.0 hangs, current main aborts with exit 134, #3742
raises a catchable RuntimeError. JACCL has none of that.

What would help

Anything that ends the wait. A timeout on the completion queue poll, or a liveness
check on the side channel, with the group reporting the loss instead of spinning.
The recovery behaviour after SIGCONT suggests the wait itself is sound and only the
unbounded part is the problem.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions