From: Jeremy Szu Date: Wed, 16 Feb 2022 00:26:46 +0800 Subject: Make sure nvidia-drm rules action processed GDM expects nvidia-drm be loaded to configures wayland or xorg: ``` KERNEL!="nvidia_drm", GOTO="gdm_nvidia_drm_end" SUBSYSTEM!="module", GOTO="gdm_nvidia_drm_end" ACTION!="add", GOTO="gdm_nvidia_drm_end" ATTR{parameters/modeset}!="Y", GOTO="gdm_disable_wayland" ``` In some race condition, the nvidia-drm was load later than gdm. gpu-manager can cover this case to prevent race condition. Tested-by: jeremy.szu@canonical.com Suggested-by: kai.heng.feng@canonical.com --- share/hybrid/71-u-d-c-gpu-detection.rules | 1 + share/hybrid/gpu-manager.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/share/hybrid/71-u-d-c-gpu-detection.rules b/share/hybrid/71-u-d-c-gpu-detection.rules index 0267a68..908f223 100644 --- a/share/hybrid/71-u-d-c-gpu-detection.rules +++ b/share/hybrid/71-u-d-c-gpu-detection.rules @@ -5,3 +5,4 @@ ACTION=="add", SUBSYSTEM=="drm", DEVPATH=="*/drm/card*", RUN+="/sbin/u-d-c-print # Create a file when a module is loaded ACTION=="add", SUBSYSTEMS=="pci", DRIVERS=="nvidia", RUN+="/bin/touch /run/u-d-c-nvidia-was-loaded" +ACTION=="add", SUBSYSTEM=="module", KERNEL=="nvidia_drm", RUN+="/bin/touch /run/u-d-c-nvidia-drm-was-loaded" diff --git a/share/hybrid/gpu-manager.c b/share/hybrid/gpu-manager.c index 0764f49..da5559a 100644 --- a/share/hybrid/gpu-manager.c +++ b/share/hybrid/gpu-manager.c @@ -83,6 +83,7 @@ static inline void pclosep(FILE **); #define LAST_BOOT "/var/lib/ubuntu-drivers-common/last_gfx_boot" #define OFFLOADING_CONF "/var/lib/ubuntu-drivers-common/requires_offloading" #define RUNTIMEPM_OVERRIDE "/etc/u-d-c-nvidia-runtimepm-override" +#define UDEV_NVIDIA_COMPLETED "/run/u-d-c-nvidia-drm-was-loaded" #define XORG_CONF "/etc/X11/xorg.conf" #define KERN_PARAM "nogpumanager" #define AMDGPU_PRO_PX "/opt/amdgpu-pro/bin/amdgpu-pro-px" @@ -3025,6 +3026,12 @@ int main(int argc, char *argv[]) { fprintf(log_handle, "Has nvidia? %s\n", (has_nvidia ? "yes" : "no")); fprintf(log_handle, "How many cards? %d\n", cards_n); + /* Probe graphic drivers earlier since some graphic related application + * (e.g. gdm, mutter) rely on udev rules to apply extra configurations. + */ + if (has_nvidia && !nvidia_blacklisted && !is_module_loaded("nvidia")) + load_module("nvidia"); + /* See if the system has changed */ has_changed = has_system_changed(old_devices, current_devices, @@ -3035,6 +3042,15 @@ int main(int argc, char *argv[]) { if (has_changed) fprintf(log_handle, "System configuration has changed\n"); + /* Make sure the udev rules are applied for graphic cards. */ + if (has_nvidia && !nvidia_blacklisted) { + for (i = 0; i < 500; i++, usleep(20000)) { + if (is_file(UDEV_NVIDIA_COMPLETED)) + break; + } + fprintf(log_handle, "Takes %dms to wait for nvidia udev rules completed.\n", i * 20); + } + if (cards_n == 1) { fprintf(log_handle, "Single card detected\n");