|
|
ff86aa |
From f76757f9dd63407686b24c98e5c2290502bcbb93 Mon Sep 17 00:00:00 2001
|
|
|
ff86aa |
From: Hans de Goede <hdegoede@redhat.com>
|
|
|
ff86aa |
Date: Tue, 26 Mar 2019 15:10:28 -0400
|
|
|
ff86aa |
Subject: [PATCH] ply-device-manager: Fix race causing undesired creation of
|
|
|
ff86aa |
non-gfx devs
|
|
|
ff86aa |
|
|
|
ff86aa |
On systems with working drm/kms devices we still sometimes see:
|
|
|
ff86aa |
"Creating non-graphical devices, since there's no suitable graphics hardware"
|
|
|
ff86aa |
in the logs (and actually create non-gfx devices).
|
|
|
ff86aa |
|
|
|
ff86aa |
This is caused by a race where the create_devices_from_udev timeout handler
|
|
|
ff86aa |
runs just after the pivot-root, just at the time when the "udev trigger"
|
|
|
ff86aa |
from the real root is done.
|
|
|
ff86aa |
|
|
|
ff86aa |
This causes create_devices_for_subsystem() to hit the "it's not initialized"
|
|
|
ff86aa |
code-path for all drm and fb devices, even though before (from the initrd)
|
|
|
ff86aa |
drm-devices where already setup successfully.
|
|
|
ff86aa |
|
|
|
ff86aa |
One way of solving this would be to stop the timer as soon as we successfully
|
|
|
ff86aa |
enumerate the first drm device. But we need the timer to enumerate fb devices
|
|
|
ff86aa |
so on machines where some outputs only have a fbdev driver (corner case) this
|
|
|
ff86aa |
would break support for those outputs.
|
|
|
ff86aa |
|
|
|
ff86aa |
Instead this commit moves the found_drm_device and found_fb_device to the
|
|
|
ff86aa |
global manager state and sets them from create_devices_for_udev_device().
|
|
|
ff86aa |
This way they will be set when we check them from the create_devices_from_udev
|
|
|
ff86aa |
timeout handler even if create_devices_for_subsystem skips over the devices
|
|
|
ff86aa |
because of the udev trigger race.
|
|
|
ff86aa |
|
|
|
ff86aa |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
ff86aa |
---
|
|
|
ff86aa |
src/libply-splash-core/ply-device-manager.c | 19 +-
|
|
|
ff86aa |
1 files changed, 63 insertions(+), 60 deletions(-)
|
|
|
ff86aa |
|
|
|
ff86aa |
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
|
|
|
ff86aa |
index 3a2db06..b6437c5 100644
|
|
|
ff86aa |
--- a/src/libply-splash-core/ply-device-manager.c
|
|
|
ff86aa |
+++ b/src/libply-splash-core/ply-device-manager.c
|
|
|
ff86aa |
@@ -47,60 +47,63 @@ static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t
|
|
|
ff86aa |
ply_renderer_type_t renderer_type);
|
|
|
ff86aa |
struct _ply_device_manager
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_device_manager_flags_t flags;
|
|
|
ff86aa |
ply_event_loop_t *loop;
|
|
|
ff86aa |
ply_hashtable_t *terminals;
|
|
|
ff86aa |
ply_hashtable_t *renderers;
|
|
|
ff86aa |
ply_terminal_t *local_console_terminal;
|
|
|
ff86aa |
ply_list_t *keyboards;
|
|
|
ff86aa |
ply_list_t *text_displays;
|
|
|
ff86aa |
ply_list_t *pixel_displays;
|
|
|
ff86aa |
struct udev *udev_context;
|
|
|
ff86aa |
struct udev_queue *udev_queue;
|
|
|
ff86aa |
int udev_queue_fd;
|
|
|
ff86aa |
ply_fd_watch_t *udev_queue_fd_watch;
|
|
|
ff86aa |
struct udev_monitor *udev_monitor;
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_keyboard_added_handler_t keyboard_added_handler;
|
|
|
ff86aa |
ply_keyboard_removed_handler_t keyboard_removed_handler;
|
|
|
ff86aa |
ply_pixel_display_added_handler_t pixel_display_added_handler;
|
|
|
ff86aa |
ply_pixel_display_removed_handler_t pixel_display_removed_handler;
|
|
|
ff86aa |
ply_text_display_added_handler_t text_display_added_handler;
|
|
|
ff86aa |
ply_text_display_removed_handler_t text_display_removed_handler;
|
|
|
ff86aa |
void *event_handler_data;
|
|
|
ff86aa |
|
|
|
ff86aa |
uint32_t local_console_managed : 1;
|
|
|
ff86aa |
uint32_t local_console_is_text : 1;
|
|
|
ff86aa |
uint32_t serial_consoles_detected : 1;
|
|
|
ff86aa |
uint32_t renderers_activated : 1;
|
|
|
ff86aa |
uint32_t keyboards_activated : 1;
|
|
|
ff86aa |
+
|
|
|
ff86aa |
+ uint32_t found_drm_device : 1;
|
|
|
ff86aa |
+ uint32_t found_fb_device : 1;
|
|
|
ff86aa |
};
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
detach_from_event_loop (ply_device_manager_t *manager)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
assert (manager != NULL);
|
|
|
ff86aa |
|
|
|
ff86aa |
manager->loop = NULL;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
attach_to_event_loop (ply_device_manager_t *manager,
|
|
|
ff86aa |
ply_event_loop_t *loop)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
assert (manager != NULL);
|
|
|
ff86aa |
assert (loop != NULL);
|
|
|
ff86aa |
assert (manager->loop == NULL);
|
|
|
ff86aa |
|
|
|
ff86aa |
manager->loop = loop;
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
|
|
|
ff86aa |
detach_from_event_loop,
|
|
|
ff86aa |
manager);
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static bool
|
|
|
ff86aa |
drm_device_in_use (ply_device_manager_t *manager,
|
|
|
ff86aa |
const char *device_path)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_renderer_t *renderer;
|
|
|
ff86aa |
@@ -183,60 +186,68 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_trace ("found DRM device %s", device_path);
|
|
|
ff86aa |
renderer_type = PLY_RENDERER_TYPE_DRM;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_trace ("found frame buffer device %s", device_path);
|
|
|
ff86aa |
if (!fb_device_has_drm_device (manager, device))
|
|
|
ff86aa |
{
|
|
|
ff86aa |
renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
else
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_trace ("ignoring, since there's a DRM device associated with it");
|
|
|
ff86aa |
}
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
if (renderer_type != PLY_RENDERER_TYPE_NONE)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_terminal_t *terminal = NULL;
|
|
|
ff86aa |
|
|
|
ff86aa |
if (!manager->local_console_managed)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
terminal = manager->local_console_terminal;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
created = create_devices_for_terminal_and_renderer_type (manager,
|
|
|
ff86aa |
device_path,
|
|
|
ff86aa |
terminal,
|
|
|
ff86aa |
renderer_type);
|
|
|
ff86aa |
+
|
|
|
ff86aa |
+ if (created)
|
|
|
ff86aa |
+ {
|
|
|
ff86aa |
+ if (renderer_type == PLY_RENDERER_TYPE_DRM)
|
|
|
ff86aa |
+ manager->found_drm_device = 1;
|
|
|
ff86aa |
+ if (renderer_type == PLY_RENDERER_TYPE_FRAME_BUFFER)
|
|
|
ff86aa |
+ manager->found_fb_device = 1;
|
|
|
ff86aa |
+ }
|
|
|
ff86aa |
}
|
|
|
ff86aa |
}
|
|
|
ff86aa |
return created;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
free_displays_for_renderer (ply_device_manager_t *manager,
|
|
|
ff86aa |
ply_renderer_t *renderer)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_list_node_t *node;
|
|
|
ff86aa |
|
|
|
ff86aa |
node = ply_list_get_first_node (manager->pixel_displays);
|
|
|
ff86aa |
while (node != NULL)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_list_node_t *next_node;
|
|
|
ff86aa |
ply_pixel_display_t *display;
|
|
|
ff86aa |
ply_renderer_t *display_renderer;
|
|
|
ff86aa |
|
|
|
ff86aa |
display = ply_list_node_get_data (node);
|
|
|
ff86aa |
next_node = ply_list_get_next_node (manager->pixel_displays, node);
|
|
|
ff86aa |
display_renderer = ply_pixel_display_get_renderer (display);
|
|
|
ff86aa |
|
|
|
ff86aa |
if (display_renderer == renderer)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
if (manager->pixel_display_removed_handler != NULL)
|
|
|
ff86aa |
manager->pixel_display_removed_handler (manager->event_handler_data, display);
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_pixel_display_free (display);
|
|
|
ff86aa |
ply_list_remove_node (manager->pixel_displays, node);
|
|
|
ff86aa |
}
|
|
|
ff86aa |
@@ -782,68 +793,66 @@ create_devices_from_terminals (ply_device_manager_t *manager)
|
|
|
ff86aa |
ply_trace ("checking for consoles");
|
|
|
ff86aa |
|
|
|
ff86aa |
if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
has_serial_consoles = false;
|
|
|
ff86aa |
ply_trace ("ignoring all consoles but default console because explicitly told to.");
|
|
|
ff86aa |
}
|
|
|
ff86aa |
else
|
|
|
ff86aa |
{
|
|
|
ff86aa |
has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
if (has_serial_consoles)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
ply_trace ("serial consoles detected, managing them with details forced");
|
|
|
ff86aa |
manager->serial_consoles_detected = true;
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_hashtable_foreach (manager->terminals,
|
|
|
ff86aa |
(ply_hashtable_foreach_func_t *)
|
|
|
ff86aa |
create_devices_for_terminal,
|
|
|
ff86aa |
manager);
|
|
|
ff86aa |
return true;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
return false;
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
create_devices_from_udev (ply_device_manager_t *manager)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
- bool found_drm_device, found_fb_device;
|
|
|
ff86aa |
-
|
|
|
ff86aa |
ply_trace ("Looking for devices from udev");
|
|
|
ff86aa |
|
|
|
ff86aa |
- found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
|
|
|
ff86aa |
- found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
|
|
|
ff86aa |
+ create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
|
|
|
ff86aa |
+ create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
|
|
|
ff86aa |
|
|
|
ff86aa |
- if (found_drm_device || found_fb_device)
|
|
|
ff86aa |
+ if (manager->found_drm_device || manager->found_fb_device)
|
|
|
ff86aa |
return;
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware");
|
|
|
ff86aa |
create_devices_for_terminal_and_renderer_type (manager,
|
|
|
ff86aa |
ply_terminal_get_name (manager->local_console_terminal),
|
|
|
ff86aa |
manager->local_console_terminal,
|
|
|
ff86aa |
PLY_RENDERER_TYPE_NONE);
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
create_fallback_devices (ply_device_manager_t *manager)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
create_devices_for_terminal_and_renderer_type (manager,
|
|
|
ff86aa |
ply_terminal_get_name (manager->local_console_terminal),
|
|
|
ff86aa |
manager->local_console_terminal,
|
|
|
ff86aa |
PLY_RENDERER_TYPE_AUTO);
|
|
|
ff86aa |
}
|
|
|
ff86aa |
|
|
|
ff86aa |
static void
|
|
|
ff86aa |
on_udev_queue_changed (ply_device_manager_t *manager)
|
|
|
ff86aa |
{
|
|
|
ff86aa |
|
|
|
ff86aa |
if (!udev_queue_get_queue_is_empty (manager->udev_queue))
|
|
|
ff86aa |
return;
|
|
|
ff86aa |
|
|
|
ff86aa |
ply_trace ("udev coldplug complete");
|
|
|
ff86aa |
ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch);
|
|
|
ff86aa |
manager->udev_queue_fd_watch = NULL;
|
|
|
ff86aa |
udev_queue_unref (manager->udev_queue);
|
|
|
ff86aa |
|
|
|
ff86aa |
--
|
|
|
ff86aa |
2.20.1
|
|
|
ff86aa |
|