[gdm/fix-udev-race: 66/66] data: Don't race with vendor nvidia driver at startup




commit b2d6ccee16df921af515efd559dcf59d5b2d0d99
Author: Ray Strode <rstrode redhat com>
Date:   Mon Feb 14 17:03:09 2022 -0500

    data: Don't race with vendor nvidia driver at startup
    
    The vendor nvidia driver has two modules loaded
    at startup.
    
    It's not uncommon for the second module to still
    be loading when GDM starts.
    
    Our udev rule relies on the second module to set
    up GDM's boot configuration.
    
    This commit adds some synchronization to stall
    GDM a bit if the vendor driver is still coming
    up.
    
    https://gitlab.gnome.org/GNOME/gdm/-/issues/763

 data/61-gdm.rules.in             | 15 ++++++++++++++-
 data/gdm-waiting-on-udev.path.in | 12 ++++++++++++
 data/gdm.service.in              |  5 +++++
 data/meson.build                 |  9 +++++++++
 4 files changed, 40 insertions(+), 1 deletion(-)
---
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index e9c726977..9451c12e7 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -9,6 +9,15 @@ DRIVERS=="simple-framebuffer", GOTO="gdm_nomodeset_end"
 IMPORT{cmdline}="nomodeset", GOTO="gdm_disable_wayland"
 LABEL="gdm_nomodeset_end"
 
+# The vendor nvidia driver has mutiple modules that need to be loaded before GDM can make an
+# informed choice on which way to proceed, so force GDM to wait until NVidia's modules are
+# loaded before starting up.
+KERNEL!="nvidia", GOTO="gdm_nvidia_end"
+SUBSYSTEM!="module", GOTO="gdm_nvidia_end"
+ACTION!="add", GOTO="gdm_nvidia_end"
+RUN+="@bindir@/touch /run/udev/gdm-waiting-on-udev"
+LABEL="gdm_nvidia_end"
+
 # Disable wayland when nvidia modeset is disabled or when drivers are a lower
 # version than 470,
 # For versions above 470 but lower than 510 prefer Xorg,
@@ -30,10 +39,14 @@ GOTO="gdm_end"
 
 LABEL="gdm_prefer_xorg"
 RUN+="@libexecdir@/gdm-runtime-config set daemon PreferredDisplayServer xorg"
-GOTO="gdm_end"
+GOTO="gdm_stop_waiting_on_udev"
 
 LABEL="gdm_disable_wayland"
 RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
+GOTO="gdm_stop_waiting_on_udev"
+
+LABEL="gdm_stop_waiting_on_udev"
+RUN+="@bindir@/rm -f /run/udev/gdm-waiting-on-udev"
 GOTO="gdm_end"
 
 LABEL="gdm_end"
diff --git a/data/gdm-waiting-on-udev.path.in b/data/gdm-waiting-on-udev.path.in
new file mode 100644
index 000000000..ceb037049
--- /dev/null
+++ b/data/gdm-waiting-on-udev.path.in
@@ -0,0 +1,12 @@
+[Unit]
+Description=Synchronize GNOME Display Manager with udev
+ConditionPathExists=/run/udev/gdm-waiting-on-udev
+
+[Path]
+PathChanged=/run/udev/gdm-waiting-on-udev
+Unit=gdm.service
+
+[Install]
+WantedBy=graphical.target
+
+
diff --git a/data/gdm.service.in b/data/gdm.service.in
index 17e8a8de8..effdf56a0 100644
--- a/data/gdm.service.in
+++ b/data/gdm.service.in
@@ -19,6 +19,11 @@ After=rc-local.service plymouth-start.service systemd-user-sessions.service
 # for any reason, make sure plymouth still stops
 OnFailure=plymouth-quit.service
 
+# If our udev rule is still trying to figure out the lay of the land
+# then block for a bit. gdm-waiting-on-udev.path will start us later
+# when appropriate.
+ConditionPathExists=!/run/udev/gdm-waiting-on-udev
+
 [Service]
 ExecStart=${sbindir}/gdm
 KillMode=mixed
diff --git a/data/meson.build b/data/meson.build
index 2dec4c232..8764abfeb 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -149,6 +149,7 @@ gdm_rules = configure_file(
   output: '@BASENAME@',
   configuration: {
     'libexecdir': gdm_prefix / get_option('libexecdir'),
+    'bindir': gdm_prefix / get_option('bindir'),
   },
   install_dir: udev_dir,
 )
@@ -185,6 +186,14 @@ configure_file(
   format: 'cmake'
 )
 
+configure_file(
+  input: 'gdm-waiting-on-udev.path.in',
+  output: '@BASENAME@',
+  configuration: service_config,
+  install_dir: systemd_systemunitdir,
+  format: 'cmake'
+)
+
 gdm_gnome_session_wanted_targets = []
 foreach component: gdm_gnome_user_session_wanted_components
   gdm_gnome_session_wanted_targets += 'Wants=@0@.target'.format(component)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]