Skip to content

fix(shmem): public RDMA quiet returned before the caller's WQEs completed#404

Merged
jhchouuu merged 2 commits into
mainfrom
jiahzhou/bnxt-get-drain-fix
Jun 17, 2026
Merged

fix(shmem): public RDMA quiet returned before the caller's WQEs completed#404
jhchouuu merged 2 commits into
mainfrom
jiahzhou/bnxt-get-drain-fix

Conversation

@jhchouuu

Copy link
Copy Markdown
Collaborator

What

The public ShmemQuietThread() and ShmemQuietThread(pe, qpId) overloads used the snapshot drain (DrainToLive=false), so under multi-warp contention on a shared QP a warp could return from quiet before its own posted WQEs completed. A GET reads its local destination right after quiet, so this yields stale data (0xDEAD); concurrent_get_thread thread-scope GET failed intermittently on bnxt.

Fix

Make both public quiet overloads real completion waits (DrainToLive=true), matching the per-PE overload. The recycle gate is unaffected — it calls ShmemQuietThreadKernelImpl directly and must stay snapshot.

Test hardening

The failure was invisible to CI because the shmem examples always returned 0 and the CI steps had no set -e. Made the CPP shmem examples return non-zero on verification failure and added set -e to the shmem CI steps.

Verification

On bnxt (P2P and IBGDA): all shmem examples pass; built against the old code, concurrent_get_thread now exits non-zero.

jhchouuu added 2 commits June 17, 2026 04:49
#395 introduced the DrainToLive split (false = snapshot recycle gate, true =
wait for live postIdx) and converted the per-PE ShmemQuietThread(pe) overload to
true, but left the public quiet-all ShmemQuietThread() and per-QP
ShmemQuietThread(pe, qpId) overloads on the default snapshot drain (false). Under
multi-warp contention on a shared QP, warps that lose the drain lock return
without waiting for their own posted WQEs to complete. A GET reads its local
destination right after quiet, so an unwaited completion yields stale data
(0xDEAD). Symptom: concurrent_get_thread thread-scope GET fails intermittently on
bnxt; block / large-chunk GET and PUT happened to mask it.

Make both public overloads real completion waits (DrainToLive=true), matching the
per-PE overload. The recycle gate is unaffected: it calls
ShmemQuietThreadKernelImpl directly with the default snapshot drain, which must
stay snapshot to avoid self-deadlock on its own un-doorbelled reservation.
Keeps #395's outstandingWqe removal and per-lane PSN fix intact.

Verified on bnxt: concurrent_get_thread passes across repeated runs (was ~4/7
subtests failing); put / atomic / put_signal / put_imm thread tests and the EP
internode correctness test (which exercises quiet-all) stay green.
The thread-scope shmem examples only printf'd PASSED/FAILED and main() always
returned 0, so failing cases never set a non-zero exit; combined with the CI
shmem steps lacking set -e (step status = last command only), broken cases passed
CI silently (this is how the bnxt GET thread-scope regression went unnoticed).

- concurrent_get_thread / concurrent_put_thread / concurrent_put_imm_thread /
  concurrent_put_signal_thread: count failed verifications and return non-zero
  from main(). Fix concurrent_put_imm_thread's verification, which was dead code
  (PE 1 verified but the PASS/FAIL prints were gated on myPe==0 inside the
  myPe==1 block, and PE 0 always printed PASSED without verifying). For
  put_thread only the RDMA put-correctness tests feed the counter; the P2P-only
  direct-access test is excluded since it is expected to differ under
  MORI_DISABLE_P2P. For put_signal, also compare the signal counter, which was
  printed but never checked.
- Add set -e to the MORI-CPP shmem (P2P) and (IBGDA) steps so any failing example
  fails the step.

The atomic examples (atomic_fetch/atomic_nonfetch) verify on the receiver via a
device-side spin, so a failure manifests as a hang -> timeout -> non-zero, now
caught by set -e.

Verified on bnxt in both P2P and IBGDA: all examples exit 0 when correct; built
against the pre-fix shmem, concurrent_get_thread exits non-zero (4/7 failing).
@jhchouuu jhchouuu merged commit 5db792f into main Jun 17, 2026
31 of 33 checks passed
@jhchouuu jhchouuu deleted the jiahzhou/bnxt-get-drain-fix branch June 17, 2026 07:43
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