Repository navigation
soc: apple: clpc: hold the T8140 GPU floor only for streaming GPU work - #464
Conversation
The T8140 GPU floor was held whenever graphics was powered. On J700 that costs 0.38 W (about 8%) during 1080p video playback in Firefox and 0.16 W during light browsing, where the floor gains nothing. The firmware powers graphics off a few milliseconds after the GPU idles. Sampled every millisecond, 1080p video powered graphics for 56% of the time and light browsing for 34%, but never for more than 63 ms at a time, while light compute and render submission streams kept it powered throughout. Count graphics as GPU demand only once it has stayed powered for 64 ms, with no sample finding it off and no gap in sampling long enough to have missed that, and sample on time while it is powered. A failed read still counts as powered. The debugfs status shows how long graphics has been powered.
…e DCS
Under sustained heavy rendering on J700, the GPU floor ended 1.8%
slower and 1.3 C hotter than no floor over 90 s, for 0.14 W more.
The PMP, voter agent 0, votes the DCS to its top state for streams of
light GPU submissions: it did for every millisecond sample of light
compute and render streams. Under heavy rendering it lowers the DCS,
to state 3 for 62% of the samples, to stay within the GPU's power
budget. The floor then only overrides that and takes headroom from the
GPU. macOS also lets the fabric drop for heavy GPU work.
While GPU work streams, read the PMP's floor word. When it votes the
DCS below the GPU floor's state, release the GPU floor and keep it
released for 1 s after the PMP last did so. The debugfs status shows
when that was.
Measured on J700 with both changes, one boot each on battery, against
no GPU floor and the floor held whenever graphics is powered:
no floor powered this
1080p video, W 4.903 5.151 4.975
light browsing, W 3.971 4.085 3.970
render.heavy d4 at 90 s, us 659.5 671.1 656.8
compute.light d1, us 373.7 320.5 319.3
render.light d2, us 87.2 65.6 66.6
The GPU floor used the top entry of each rail's CPU table, so raising the fabric for GPU work also raised it for a CPU cluster in its top frequency quartile. On J700 that costs 0.21 W during a single-thread load (6.738 -> 6.948 W), and no CPU benefit has been measured. Give each SoC a GPU target separate from its CPU table. T8140 keeps DCS 4 and fabric 3 for streaming GPU work, and its CPU table no longer touches the fabric, as before the GPU floor. T8132's GPU target is its CPU table's top entry, so it is unchanged.
The 64 ms streaming gate and the PMP back-off were measured on T8140 but sat on the shared graphics path, so they also changed T8132. That SoC had no DT consumer yet, but it would have lost its floor for bursts under 64 ms, against what was qualified there. Make the time graphics must stay powered a per-SoC parameter: 64 ms on T8140, and 0 on T8132, which keeps that SoC's floor whenever graphics is powered, as before. The PMP back-off was already T8140 only. The debugfs status now says "never" when the PMP has not limited the DCS, rather than 0 ms ago. The comment no longer says a failed read cannot starve a graphics consumer: a failed read counts as powered, so read errors alone do not end a stream that is already under way.
|
Updated with the two follow-ups from the omacom review (omacom/linux-aurora#226):
Both build with W=1 against the 7.3 tree, and checkpatch is clean. |
|
Qualification on Neo (J700) of integration/aurora 501e607 with this PR merged, as a full kernel (7.3.0-ARCH-neo464, build b60d9067, own modules). The A/B baseline was the current perf core with the same asahi source. Both arms ran in one session; the machine was charging throughout, so absolute watts are higher than on battery.
One regression blocks the merge: light work right after the PMP limited the DCS. compute.light d1, per 250 ms run:
The first 0.5–0.75 s of light submissions run about 47% slower before the floor comes back. That's the 1 s hold after the PMP last limited the DCS (rule 2). The rows that came after heavier work start with the floor released. Proposed fix: end the PMP backoff when the PMP stops limiting, after a short hysteresis of tens of ms rather than a fixed 1 s. Heavy sustained work keeps the benefit, and light work that follows gets the floor back within the streaming gate. I'll requalify it the same way before merging, and the same change goes to omacom/linux-aurora#226. |
…stops limiting The GPU floor stayed released for a second after the PMP last limited the DCS. Light GPU work that followed heavier work therefore ran without the floor for up to that second: on Neo, compute.light d1 took 148-151 us instead of 102.7 us for the first 0.5-0.75 s of a run, before the floor came back. Under sustained heavy rendering the PMP limits the DCS again within much less than that, so a 100 ms hold keeps the floor released there while the light work that follows gets it back almost at once.
|
Requalified with 51350a0 (hand the T8140 GPU floor back 100 ms after the PMP stops limiting, instead of 1 s). Full kernel: integration/aurora 501e607 + this PR, kernel build 976a26ad, on Neo (J700), same session as the baseline (default core + the same asahi source). The blocker from the first run is gone: compute.light d1 is 102.75 µs [102.59–103.05] across rounds vs 102.80 [102.71–102.84] baseline. Run 1 with the 1 s hold showed 117.2 [103.0–135.6], the first 0.5–0.75 s after heavier rows.
Light rows are unchanged (µs/submit): compute.light d2 34.04 → 33.75, render.light d2 46.04 → 46.09, render.light d32 27.12 → 27.13. Gate: PERFORMANCE-REGRESSION-PASS. Targeted CTS: 4687 pass / 681 not supported / 0 fail. No CLPC/asahi kernel errors. Merging. |
Summary
The T8140 GPU floor from #440 (DCS 4, fabric 3) is held whenever graphics is powered. On J700 that costs power where it buys nothing: +0.25 W (5%) during 1080p video in Firefox, +0.11 W during light browsing. Under sustained heavy rendering, the floor also ends slower and hotter than no floor. Two changes restrict it to what it is for, streams of light GPU submissions:
The same change is omacom/linux-aurora#226, where maralcbr asked for it. The first commit is adapted to this tree, which has no graphics read-error counter: a failed read still counts as powered.
Measurements
Neo (J700), one boot per kernel in a single session, on battery. These were taken on the 7.2.11 omacom base of #226 (19f4965 + #226 + #227 + #228), where the CLPC driver differs only in that read-error counter. "Powered" is the floor as merged in #440; "this" is these two commits.
The fabric floor was held for 21% of the video leg (was 100%), 2% of browsing (was 51%) and 5% of the heavy leg (was 100%). Light submissions keep the floor's gain.
Testing
statusline now shows how long graphics has been powered and when the PMP last limited the DCS.