Hotplugging USB DRM device does not always send enough RandR events
When hotplugging a DisplayLink USB 3 dock for the first time after a reboot, GNOME/Xorg does not take the new output automatically into use like it should. I'm not sure if this is an Xorg or Mutter issue, but to me at the moment it looks more like an Xorg issue.
This issue is observed on Ubuntu 19.04 with GNOME/Xorg. Xorg is 1.20.4 based with a bunch of patches, particularly a version of 078277e4 which makes the new DRM device offer its outputs on SCREEN 0. Otherwise nothing would happen anyway.
This is probably a race in its nature, since I could not reproduce it with a self-built Xorg using the Ubuntu patches and the same GNOME with which I can quite reliably reproduce it with the Ubuntu distributed Xorg. I did add more prints in the modesetting driver, those might affect timings.
I cannot test this on Xorg master because of regressions that cause Xorg to crash on DisplayLink hotplug.
I did add some debug prints in Mutter. The following is a trace with that and udevadm monitor -p -u -s drm
.
Doing the DisplayLink USB hotplug the first time will cause the EVDI kernel driver to create a new DRM device node.
UDEV [209.749468] add /devices/platform/evdi.0/drm/card1 (drm)
ACTION=add
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7484
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:seat:uaccess:snap_chromium_chromedriver:snap_chromium_chromium:master-of-seat:
UDEV [209.756119] add /devices/platform/evdi.0/drm/card1/card1-DVI-I-1 (drm)
ACTION=add
DEVPATH=/devices/platform/evdi.0/drm/card1/card1-DVI-I-1
SUBSYSTEM=drm
SEQNUM=7485
USEC_INITIALIZED=209750904
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
TAGS=:snap_chromium_chromium:snap_chromium_chromedriver:master-of-seat:seat:
UDEV [209.760618] change /devices/platform/evdi.0/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7486
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:master-of-seat:seat:uaccess:snap_chromium_chromedriver:snap_chromium_chromium:
UDEV [210.172356] change /devices/platform/evdi.0/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7488
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:snap_chromium_chromedriver:seat:master-of-seat:uaccess:snap_chromium_chromium:
(gnome-shell:3088): mutter-DEBUG: 12:14:38.844: expose for stage: win:0x2400011 - redrawing area (x: 0, y: 0, width: 1366, height: 768)
meta_monitor_manager_xrandr_handle_xevent: is_hotplug no, is_our_configuration no
event->timestamp 209365, event->config_timestamp 34565
resources->timestamp 209365, resources->configTimestamp 34565
UDEV [210.761047] change /devices/platform/evdi.0/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7489
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:master-of-seat:uaccess:snap_chromium_chromedriver:snap_chromium_chromium:seat:
Notice meta_monitor_manager_xrandr_handle_xevent: is_hotplug no
from Mutter indicating that it thinks it was just someone playing with xrandr
so there is no need to enable newly appeared outputs. Comparing the config_timestamp
with UDEV events (if that makes sense?), it looks like the config would be from around the time Xorg initially started.
At this point, checking with xrandr --current
shows the correct mode list on the DisplayLink connector and says it is connected.
Then unplugging the DisplayLink dock simply makes the DRM connector disconnected in the kernel, and this seems to be handled correctly:
UDEV [284.796057] change /devices/platform/evdi.0/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7554
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:uaccess:seat:master-of-seat:snap_chromium_chromium:snap_chromium_chromedriver:
meta_monitor_manager_xrandr_handle_xevent: is_hotplug yes, is_our_configuration no
event->timestamp 209365, event->config_timestamp 284795
resources->timestamp 209365, resources->configTimestamp 284795
The event is detected as hotplug, but of course there is nothing to do, since the output was not active.
Plugging the DisplayLink dock back in, the hotplug is processed correctly:
UDEV [312.125971] change /devices/platform/evdi.0/drm/card1 (drm)
ACTION=change
DEVPATH=/devices/platform/evdi.0/drm/card1
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=/dev/dri/card1
DEVTYPE=drm_minor
SEQNUM=7671
USEC_INITIALIZED=209744011
ID_PATH=platform-evdi.0
ID_PATH_TAG=platform-evdi_0
ID_FOR_SEAT=drm-platform-evdi_0
MAJOR=226
MINOR=1
DEVLINKS=/dev/dri/by-path/platform-evdi.0-card
TAGS=:snap_chromium_chromium:master-of-seat:seat:snap_chromium_chromedriver:uaccess:
meta_monitor_manager_xrandr_handle_xevent: is_hotplug yes, is_our_configuration no
event->timestamp 209365, event->config_timestamp 312126
resources->timestamp 209365, resources->configTimestamp 312126
(gnome-shell:3088): mutter-DEBUG: 12:16:20.851: expose for stage: win:0x2400011 - redrawing area (x: 0, y: 0, width: 1366, height: 768)
meta_monitor_manager_xrandr_handle_xevent: is_hotplug no, is_our_configuration yes
event->timestamp 209365, event->config_timestamp 312126
resources->timestamp 312588, resources->configTimestamp 312126
meta_monitor_manager_xrandr_handle_xevent: is_hotplug no, is_our_configuration yes
event->timestamp 312588, event->config_timestamp 312126
resources->timestamp 312588, resources->configTimestamp 312126
meta_monitor_manager_xrandr_handle_xevent: is_hotplug no, is_our_configuration yes
event->timestamp 312588, event->config_timestamp 312126
resources->timestamp 312588, resources->configTimestamp 312126
(gnome-shell:3088): mutter-DEBUG: 12:16:21.413: ConfigureNotify[2400011] (3286, 1080)
(gnome-shell:3088): mutter-DEBUG: 12:16:21.413: expose for stage: win:0x2400011 - redrawing area (x: 0, y: 0, width: 3286, height: 1080)
This time the DRM device node was pre-existing, the connector just changes status to connected, and Mutter activates the output as expected.