Skip to content

Allow DisplayPort detach bookkeeping when the sink is unplugged - #1359

Open
martinstark wants to merge 2 commits into
NVIDIA:mainfrom
martinstark:fix/dp-detach-unplugged
Open

martinstark wants to merge 2 commits into
NVIDIA:mainfrom
martinstark:fix/dp-detach-unplugged

Conversation

@martinstark

@martinstark martinstark commented Sep 14, 2026

Copy link
Copy Markdown

Power-cycling a Dell U2725QE on 615.71.09 can leave DPLib tracking detached heads, breaking subsequent 4K120 setup. This patch restores detach cleanup and same-connector recovery in the tested setup.

Cause and fix

All four previousPlugged modeset guards were introduced in 615.71.09 (dpPreModeset() guard); 610.57.04 has none. dpPreModeset() rejects unplugged detach, leaving dpPostModeset() nothing to complete. NVKMS detaches hardware, clears its head bit and removes group devices; DPLib retains its per-head pointer and an empty, attached activeGroups entry.

With stale groups present, ConnectorImpl2x::enableFlush() proceeds past its early-return checks and attempts flush phase 1. Phase 1 returns 0x40 (NV_ERR_INVALID_STATE), aborting trainLinkOptimized() before hardware training or sink DSC enable. The firmware-side rejection reason is unavailable.

Every selected head is checked before mutation: allow HPD-low detach-only requests; reject any request containing an attachment target. Connector/discovery guards, forced-connected/DDS exceptions and DSC/flush/training policy remain unchanged. Existing detach callbacks and unplug discovery completion already permit cleanup around the hardware update.

Reproduction

RTX 5090, direct DisplayPort, Arch Linux, Sway/Wayland, kernel 7.2.4-arch1-2, NVIDIA modules/userspace 615.71.09. Both modes use 3840×2160/four lanes: 60 Hz at 5.4 Gbit/s without DSC/FEC; 120 Hz at 8.1 Gbit/s with DSC/FEC.

  1. Fresh boot at 60 Hz; power off for ~10 seconds, then on. The picture can return with stale state.
  2. Select 120 Hz: no signal. Another power cycle fails; moving the cable to another GPU connector recovers it.

Power-cycling from working 120 Hz also fails on stock 615.71.09. Expected: same-connector recovery.

Evidence and limits

Pinned evidence: sanitized timestamped logs, diagnostic patches, control-flow harness and build/reproduction instructions. Instrumentation is excluded from this PR.

Capture Result
Before: display 0x800, SOR 1 Stale head 2 remains attached; head 3 requests DSC. Flush phase 1 returns 0x40; attach-training result is false.
Fixed: display 0x200, SOR 0 HPD-low detach (headMask=0x8) completes; group/transition lists are empty at rediscovery. Head 3 reattaches at 120 Hz; first training attempt, FEC and sink DSC enable succeed.

Captures use separate boots/connector assignments. The fixed capture covers one instrumented 120 Hz cycle on the same connector: no phase-1 failure or 0x40, but AUX errors persist during power-off/rediscovery. The nv-modeset-kernel.o build and control-flow checks passed. Not tested on hardware: diagnostic-free build, MST, UHBR, eDP/DDS, multi-head/head reassignment, other GPUs and repeated-cycle reliability.

Potentially related: NVIDIA bug 6760883, RTX 5090/Samsung G95NC wake regression (tracking acknowledgement).

AI tools assisted with investigation, patch development and this write-up. I performed the hardware tests.

The HPD check in dpPreModeset() rejects detach-only requests after unplug. This skips DP library cleanup while NVKMS advances its head bookkeeping, leaving stale attached groups that can block subsequent link training.

Allow detach-only requests when HPD is low. Reject requests with an attachment target on any selected head, preserving the connector/discovery guards and forced-connected and dynamic-mux exceptions.
@martinstark
martinstark marked this pull request as ready for review September 14, 2026 08:16
@CLAassistant

CLAassistant commented Sep 14, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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.

2 participants