Skip to content

feat(iouring): recv-arming witnesses (RecvResumeWhileRecvInFlight, RecvDoubleArmed, RecvCQEUnaccounted) and the BP-swept oracle that measured #484/#560 (celeris#586) - #597

Merged
FumingPower3925 merged 1 commit into
mainfrom
measure/586-double-arm-counters
Sep 13, 2026

Conversation

@FumingPower3925

Copy link
Copy Markdown
Contributor

The counters and test changes that measured #586 (report and skeptic review on the issue; both skeptics accept the measurement). connState.recvOutstanding tracks the two SQE placement sites against the terminal recv CQE; EngineMetrics gains RecvResumeWhileCancelPending, RecvResumeWhileRecvInFlight (the narrow window witness), RecvArmDeclined, RecvDoubleArmed and RecvCQEUnaccounted (a terminal recv CQE the bookkeeping did not expect: the kernel-side witness of a double arm). One atomic op per event, none per request. The inbound-sequence oracle prints the counters after settle and hard-asserts RecvCQEUnaccounted == 0 and RecvDoubleArmed == 0; WS484_BP is swept so the resume-during-cancel window is actually entered (at the fixture default of 256 neither build enters it in 24 runs).

Measured: at BP=8 the fixed tree shows 12 window entries with 0 unaccounted / 0 double-armed / 0 parse errors in 12/12 runs, the guard-removed control shows 6441 placements and corrupts frames in 8/12 runs. Also exposed #596 (stale recvCancelPending), fixed separately.

…t the BP that opens the #484 window

Adds four engine-wide witnesses to the io_uring worker and exports them
through engine.EngineMetrics, plus a per-conn recvOutstanding count:

  RecvResumeWhileCancelPending  resume processed with recvCancelPending set
  RecvResumeWhileRecvInFlight   ...and the cancelled recv still armed (the
                                exact celeris#484 window; the pending flag
                                alone also counts resumes after a cancel
                                that MISSED, so it over-approximates ~1000x)
  RecvArmDeclined               prepareRecv declined an arm (recvArmed)
  RecvDoubleArmed               a second recv SQE placed on one conn
                                (recvOutstanding reached 2), any site
  RecvCQEUnaccounted            terminal recv CQE for a live conn with
                                recvOutstanding == 0: a kernel-held recv
                                the bookkeeping never counted. The only
                                witness independent of cs.recvArmed.

Direct atomic adds, not per-iteration batches: the batch flush runs
before drainDetachQueue and is skipped when the loop returns, and these
are per-event invariants where one event refutes.

The WS484 oracle reads them after settle() and hard-asserts
RecvDoubleArmed == 0 and RecvCQEUnaccounted == 0 on io_uring. Two new
socketpair tests drive the real call sites (drainDetachQueue pause ->
resume before any reap -> -ECANCELED re-arm -> data CQE), and the stale
bookkeeping case the guard cannot see.

Measured (docker golang:1.27, kernel 7.0.12-linuxkit, 4 cpus, memlock
128 MiB, workers=4 in every run, single-shot io_uring subtest ALONE,
96 conns x 4 bursts x 16000 frames, no -race). N=12 per build per BP;
control = guard turned into a count + dirty-list guard reverted:

  BP    build    windows(InFlight)  doubleArmed  cqeUnaccounted  parseErr  PASS
  8     control  12 in 9/12 runs    6441          0              11 (8 runs)  3/12
  8     fixed    12 in 7/12 runs    0             0              0            12/12
  16    control   6 in 5/12         2818          0              4 (4 runs)   7/12
  16    fixed     9 in 3/12         0             0              0            12/12
  32    control   9 in 3/12         6322          0              7 (3 runs)   9/12
  32    fixed     4 in 3/12         0             0              0            12/12
  256   control   0 in 0/12         0             0              0            12/12
  256   fixed     0 in 0/12         0             0              0            12/12
  1e6   both      0                 0             0              0            24/24
  8     stale     4 in 4/12         0             131760         4 (4 runs)   0/12

Chosen BP = 8. At the fixture default (256) neither build enters the
window in 24 runs, so the pre-existing 0/24 vs 0/24 had no power. On the
fixed tree at BP=8 the window is entered 12 times and RecvDoubleArmed
and RecvCQEUnaccounted stay 0 with parseErr 0; on the control every
window entry places a second recv and the twin recvs stay doubled for
the rest of the connection (doubleArmed is amplified, armDeclined equals
the window count) and 8 of 12 runs corrupt frames. The stale-bookkeeping
build (recvArmed cleared after the pause cancel) corrupts frames in 4 of
12 runs with RecvDoubleArmed 0 in all of them and RecvCQEUnaccounted
~11000 per run: the kernel-side witness sees what the userspace guard
cannot.

Unit tests under -race: fixed tree 3/3 pass; control fails
TestPrepareRecvRefusesSecondArm (pending 1->2) and
TestResumeBeforeCancelLandsPlacesNoSecondRecv (doubleArmed 1); the
stale build fails the honest window test and passes the witness test.
@FumingPower3925 FumingPower3925 added this to the v1.6.0 milestone Sep 13, 2026
@FumingPower3925
FumingPower3925 merged commit 7e8ea4b into main Sep 13, 2026
10 checks passed
@FumingPower3925
FumingPower3925 deleted the measure/586-double-arm-counters branch September 13, 2026 20:34
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