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>
|
Tested this on a MacBook Air (M1, 2020), J313 / T8103, running This is DisplayPort Alt Mode over USB-C. Before applying the patch, a failed hot-unplug could leave the external display unusable until reboot. With the patch applied, repeated unplug/replug cycles recover without reboot. In the same boot I observed:
One captured sequence hit the poweroff clear-swap timeout at 13:59:08, then reconnected successfully with HPD asserted and 28 modes published at 13:59:20. Further hotplug cycles continued to recover. So this reproduces the exact timeout path on J313 and confirms that not latching |
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.