From 4aea5ef8e9184ae08f62c0f1bbb61727498c2d37 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Oct 2026 03:42:59 +0900 Subject: [PATCH] udev: lower priority of events triggered by device monitor Commit 905a89a2199d68fbdf2933a724c0c3aba3ae0f57 raised the priority of events triggered by the device monitor, so that the queue file would not be removed while the netlink socket in the device monitor still had a queued uevent. However, that causes a problem: when udevd receives a flood of uevents, sigchld and notification events from the workers are postponed. As a result, the queued events may not be processed during the flood, and udevd's memory consumption keeps increasing. Let's lower the priority of these events again. To avoid removing the queue file while a uevent is still pending on the netlink socket, check whether the event source corresponding to the device monitor is pending. Follow-up for 905a89a2199d68fbdf2933a724c0c3aba3ae0f57. Fixes #43865. (cherry picked from commit bca7d4ab23e90ec8859fbaeadaa5e0ae9e51b398) --- src/udev/udev-manager.c | 5 +++++ src/udev/udev-manager.h | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index b204b9abfb..d218b8bef7 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -1307,6 +1307,11 @@ static int on_post(sd_event_source *s, void *userdata) { return 0; } + /* Check whether there are uevents not received yet. If so, we will soon receive them. Do not remove + * the queue file and do not kill workers. */ + if (sd_event_source_get_pending(sd_device_monitor_get_event_source(manager->monitor)) != 0) + return 0; + (void) manager_unlink_queue_file(manager); (void) manager_reset_kill_workers_timer(manager); diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h index 1b5db6e3b6..9ff81acd9f 100644 --- a/src/udev/udev-manager.h +++ b/src/udev/udev-manager.h @@ -14,20 +14,20 @@ * inotify event source stopped as soon as possible when the signal is received. Otherwise, we may continue * receive events that needs to be serialized anyway. */ #define EVENT_PRIORITY_SIGTERM (SD_EVENT_PRIORITY_NORMAL - 6) -/* This must have a higher priority than the inotify event source, to make 'remove' uevent received earlier - * than IN_IGNORED inotify event. */ -#define EVENT_PRIORITY_DEVICE_MONITOR (SD_EVENT_PRIORITY_NORMAL - 5) /* This must have a higher priority than the worker notification, to make IN_IGNORED event received earlier * than notifications about requests of adding/removing inotify watches. */ -#define EVENT_PRIORITY_INOTIFY_WATCH (SD_EVENT_PRIORITY_NORMAL - 4) +#define EVENT_PRIORITY_INOTIFY_WATCH (SD_EVENT_PRIORITY_NORMAL - 5) /* This must have a higher priority than the worker exit event, to make notifications about completions of * processing events received before exit. */ -#define EVENT_PRIORITY_WORKER_NOTIFY (SD_EVENT_PRIORITY_NORMAL - 3) +#define EVENT_PRIORITY_WORKER_NOTIFY (SD_EVENT_PRIORITY_NORMAL - 4) /* This should have a higher priority than timer events about killing long running worker processes or idle * worker processes. */ -#define EVENT_PRIORITY_WORKER_EXIT (SD_EVENT_PRIORITY_NORMAL - 2) -/* As said in the above, this should have a lower proority than the exit event source. */ -#define EVENT_PRIORITY_WORKER_TIMER (SD_EVENT_PRIORITY_NORMAL - 1) +#define EVENT_PRIORITY_WORKER_EXIT (SD_EVENT_PRIORITY_NORMAL - 3) +/* As mentioned above, this should have a lower priority than the exit event source. */ +#define EVENT_PRIORITY_WORKER_TIMER (SD_EVENT_PRIORITY_NORMAL - 2) +/* This must have a lower priority than the worker event source. Otherwise, flood of uevents delays worker + * sigchld events or notifications, and workers will not continue to process events. */ +#define EVENT_PRIORITY_DEVICE_MONITOR (SD_EVENT_PRIORITY_NORMAL - 1) /* This should have a lower priority than most event sources, but let's process earlier than varlink and the * legacy control socket. */ #define EVENT_PRIORITY_SIGHUP (SD_EVENT_PRIORITY_NORMAL + 1)