drm/apple: don't latch ->crashed on a poweroff swap timeout - #582
Open
haripako wants to merge 1 commit into
Open
drm/apple: don't latch ->crashed on a poweroff swap timeout#582haripako wants to merge 1 commit into
haripako wants to merge 1 commit into
Conversation
iomfb_poweroff() submits a clear swap and waits 50 ms for the DCP to acknowledge it. On timeout it sets dcp->crashed and returns, without logging anything. That flag is permanent and fatal. dcp_crtc_atomic_check() starts with: if (dcp->crashed) return -EINVAL; so from that moment on every atomic commit for the device is rejected. There is no path that clears the flag, so the display never comes back until the machine is rebooted. This is not a crash. After the timeout the DCP keeps working: it renegotiates the link, publishes its mode list and asserts HPD (dcp_hotplug() connected:1 nr_modes:23). Only ->crashed, which is otherwise set exclusively by dcp_rtk_crashed() - the RTKit crash callback - makes the device unusable. RTKit never reported a crash in any of these runs. Observed on a MacBook Pro 13" M1 (j293) with DisplayPort alt mode over USB-C. Cold plug works, but the first hot unplug kills the external output for the rest of the boot. The compositor logs "failed to commit: Invalid argument" for all 23 modes the monitor offers, from 3440x1440 down to 640x480, and nothing in the kernel log explains why: of the three -EINVAL exits in dcp_crtc_atomic_check() only two log a dev_err, and the silent one is this. Confirmed with kprobes placed on each of the three exits: 110 hits on the ->crashed branch, all returning -22, with zero "DCP has crashed" messages in the log. The timeout is intermittent - it fired on 2 of 6 unplug cycles - which is why the failure looked erratic. Note that dcp_poweroff() is reached from apple_crtc_atomic_disable() for any CRTC being disabled, not just an external one, so the same timeout can in principle latch the flag while turning off the internal panel. That path was not reproduced here. Keep the control flow identical but leave ->crashed alone, and warn so the timeout is at least visible. With this applied, 6 unplug/replug cycles completed 8 modesets with no failures, including the two cycles where the timeout did fire. Signed-off-by: Francisco Vargas <haripako@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
iomfb_poweroff()waits 50 ms for the poweroff clear swap and, on timeout, setsdcp->crashedand returns without logging anything.That flag is permanent and fatal.
dcp_crtc_atomic_check()opens withif (dcp->crashed) return -EINVAL;and nothing ever clears it, so from thatmoment every atomic commit for the device is rejected and the display does not
come back until reboot.
It is not a crash. After the timeout the DCP keeps working — it renegotiates the
link, publishes its mode list and asserts HPD (
dcp_hotplug() connected:1 nr_modes:23).->crashedis otherwise set only bydcp_rtk_crashed(), theRTKit crash callback, which also logs. RTKit reported no crash in any of these
runs.
This keeps the control flow identical, leaves
->crashedalone and emits adev_warnso the timeout is visible at all.How it was found
Observed on a MacBook Pro 13" M1 (j293) driving DisplayPort alt mode over USB-C.
Cold plug works; the first hot unplug kills the external output for the rest of
the boot. The compositor logs
failed to commit: Invalid argumentfor all 23modes the monitor offers, from 3440x1440 down to 640x480, and nothing in the
kernel log explains it — of the three
-EINVALexits indcp_crtc_atomic_check()only two log adev_err, and the silent one is this.Confirmed with kprobes on each of the three exits: 110 hits on the
->crashedbranch, all returning -22, with zero "DCP has crashed" messages. The timeout is
intermittent — it fired on 2 of 6 unplug cycles — which is why the failure looked
erratic.
With this applied, 6 unplug/replug cycles completed 8 modesets with no failures,
including the two cycles where the timeout did fire.
Full traces and the validation run are at
https://github.com/haripako/dp-altmode (
validacion/).Notes
linux-asahi7.1.6 (asahi-7.1.6-1); the patch applies unchanged toasahias of today, where the code is still present.iomfb_template.cis included once per IOMFB version, so this covers both thev12_3 and v13_3 paths.
and a backport of the
fairydustcd321x HPD forwarding. This fix isindependent of both — it is in the poweroff path and applies to any CRTC
being disabled, including the internal panel, though that path was not
reproduced here.