Repository navigation
soc: apple: mailbox: arm the T6050 fast receive poller with an atomic flag - #1739
joshuaswarren wants to merge 1 commit into
Conversation
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b16d4c9362
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| hrtimer_cancel(&priv->rx_fast_timer); | ||
| atomic_set(&priv->rx_fast_armed, 0); |
There was a problem hiding this comment.
Serialize cancellation and flag reset against kicks
During a stop/warm restart with an in-flight RTKit reply, a kick can win the 0→1 exchange but not yet reach hrtimer_start(). hrtimer_cancel() then finds no active timer, this reset clears the sender's ownership, and the sender queues a timer with rx_fast_armed == 0. This is reachable because apple_rtkit_detach_rx() stops the mailbox before apple_rtkit_warm_restart() drains rtk->wq, so an already-running receive worker can still send. If a quick restart lets that timer run during its grace period, another send can enqueue it while its callback calls hrtimer_forward_now(), triggering the queued-timer warning or racing the expiry update. Exclude concurrent kicks while cancelling and resetting ownership.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
[Joshua's agent] This is the same window an earlier review found, and 391eb78 closes it. The comment is on the old commit b16d4c9, where the cancel helper reset the flag unconditionally.
The helper now clears the flag only when hrtimer_cancel() removed a queued timer. A kick that has taken the flag but has not reached hrtimer_start() keeps its ownership, and its timer starts afterwards. A tick that is running when the cancel arrives clears the flag itself on every NORESTART exit, so no idle timer is left holding a stale flag.
The new KUnit case apple_g17_fast_rx_cancel_keeps_inflight_kick_test covers it: the flag survives a cancel with no queued timer, and a cancel of a queued timer clears it. With the old unconditional reset restored, that case fails at its first assertion. Under arm64 QEMU the suite gives 5 pass and 1 skip, the skip being the uclamp case that needs CONFIG_UCLAMP_TASK.
The stop and warm restart interleaving itself is not run on hardware yet. The latency run will exercise it.
|
GREEN at b16d4c9 Joshua's agent review (lane w7X, a non-Claude reviewer working for Joshua Warren). Scope Main gave me: the race correctness of the kick/tick handoff and the KUnit race case. I did not boot hardware. CI caveat, up front: at the time of posting the PR's own checks The handoff is correct. The state is one flag F (
KUnit, which I ran myself: worktree at this head, My mutations of
Findings, none blocking:
On RyanTheTide's |
… flag A kick that arrived while the fast poll tick was returning without a restart saw an active timer, started nothing, and was lost until the next jiffy poll or send. Swapping the hrtimer_active() check for !hrtimer_is_queued() does not fix this: the tick forwards its own timer, and hrtimer_forward() needs the timer not to be enqueued by anyone else. Add rx_fast_armed. A kick starts the timer only when it moves the flag from 0 to 1, and the tick keeps the flag while it restarts. When the tick finds the deadline passed it clears the flag and reads the deadline again, so a kick that saw the flag set is picked up instead of lost. The stop and quiesce paths use one helper that cancels the timer and clears the flag. Two KUnit cases cover the single arm and the lost-kick recheck. With the recheck removed the second case fails. Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
b16d4c9 to
391eb78
Compare
|
[Joshua's agent] I pushed 391eb78 after reviewing the first revision. It closes two lost-wakeup windows in the arming flag. The cancel helper was clearing the flag even when no timer was queued. A kick that had already taken the flag could have its timer started while the flag read 0. It now clears the flag only when it cancels a queued timer. The tick's early exit for an inactive or removing mailbox was dropping the flag without the deadline recheck. A kick that raced a resume could lose its poll. It now uses the same recheck as the normal exit. The KUnit cases changed as well. The race case no longer sleeps past the kick deadline. It checks that the kick moved the deadline and that the recheck keeps the flag. A third case covers the cancel with an in-flight kick and with a queued timer. Under arm64 QEMU the suite gives 5 pass and 1 skip (the uclamp case needs CONFIG_UCLAMP_TASK). With the cancel fix reverted, the in-flight case fails. The review didn't exercise the real tick function, so the early-exit change has no unit test. It will get hardware numbers in the latency run. |
|
@joshuaswarren the flag handling and the cancel helper look right to me, and KUnit covers the race. Before merge, please post the boot on the M5 Max you mentioned: GPU mailbox receive latency with and without the patch, and at least one warm restart or s2idle cycle of a T6050 coprocessor with the patch, with no hrtimer warnings in dmesg. |
|
[Joshua's agent] Boot results for 391eb78 on a 14-inch MacBook Pro with M5 Max (T6050), 2026-11-13. What ran: the patch is the only mailbox change in both patched kernels. The first patched kernel (comb1) also carries a Wi-Fi trace commit. The second (comb2) is comb1 plus an RTKit crash-log fix. The unpatched baseline is the same tree without those commits.
The patched kernel is not slower. Runs rise across a series on both kernels. I read that as heat or clock steps. The data shows no speedup, and it does not measure receive latency.
Limit: frame-loop timing only, no receive-latency probe, one suspend cycle, one machine. |
|
@joshuaswarren a heads-up: #1844 now removes the T6050 GPU mailbox fast-receive poller entirely. Following a direction from the project owner, those mailboxes receive by interrupt like the other ASC mailboxes, and |
|
[Joshua's agent] Thanks, @DjDeveloperr. Agreed: #1844 is now merged (adb5a7e), so the T6050 fast-poll timer and the kick/tick race addressed here are gone. I see no remaining T6050 case requiring #1739 after that change; this PR is superseded there. I am not extending that conclusion to the separate T8152/ASCWrap v8 poller. Our earlier numbers remain historical polling-versus-polling results, not evidence against interrupts: the unpatched baseline already had the #1601 poller, while comb1/comb2 added the arming fix. The 6000-frame vkcube means (985 ms baseline; 958 ms patched at similar uptime, 842 ms later) were whole frame-loop wall times, not mailbox receive latency, and drifted within each series. They establish neither a receive-latency improvement nor an interrupt-versus-polling throughput comparison. The successful s2idle and zero hrtimer-warning observations apply only to those recorded polling builds. The M5 is back on comb3c today; that recovery/desktop check is not a #1844 A/B run. We have no new interrupt-path timing or power result on this 14-inch K114c, and cannot transfer the J716c inference gains in #1844 to this machine without a matched rerun. No timing claim from our earlier comment should be used to retain the removed poller. |
|
Thanks @joshuaswarren, and thanks for the careful race analysis here. As you noted, #1844 (merged as adb5a7e) superseded this PR. The maintainer's direction is that mailboxes are always driven by interrupts, so the T6050 fast-receive poller and the kick/tick race it needed are gone. Could you close this one? If you find something that still applies on the interrupt path, a fresh PR against current |
This is a follow-up to #1601. In that thread, RyanTheTide suggested replacing the
hrtimer_active()check in the send path with!hrtimer_is_queued(). I didn't take that swap. The tick forwards its own timer, andhrtimer_forward()requires the timer not be enqueued by anyone else at that moment. A kick that saw the timer as not queued while the tick was running could start it under the tick.This change keeps one flag,
rx_fast_armed. A kick starts the timer only when it moves the flag from 0 to 1. The tick keeps the flag while it restarts. When the tick finds the deadline passed, it clears the flag and reads the deadline again. A kick that landed in between saw the flag set and started nothing, so the tick takes the flag back and restarts. Before, that kick was lost until the next jiffy poll or send.The stop and quiesce paths now use one helper that cancels the timer and clears the flag.
Tests: two KUnit cases in
mailbox-g17-test.h, run on arm64 under QEMU withapple_firmware-style config (KUNIT,ARCH_APPLE,PM,APPLE_MAILBOX). One checks that only the 0 to 1 kick starts the timer. The other models the race and fails when the recheck is removed. I removed it to confirm: 3 pass, 1 fail. With the recheck in place the suite reports 4 pass, 1 skip. The skip is the existing uclamp test, which needsCONFIG_UCLAMP_TASK.checkpatch --strictis clean.Not booted yet. I will boot it on a 14-inch M5 Max MacBook Pro and measure GPU mailbox receive latency with and without this patch, then post the numbers here.