From: Kay Sievers Date: Sun, 7 Oct 2012 16:21:38 +0000 (+0200) Subject: udev: allow firmware requests to bypass the dependency tracking X-Git-Tag: v195~159 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=ea6039a30929ff845859ed601594546d71894d84;ds=sidebyside udev: allow firmware requests to bypass the dependency tracking The removal of the TIMEOUT= handling in udevd put firmware requests into the devpath parent/child dependency tracking. Drivers which block in module_init() asking userspace for firmware ran into a 30 sec device timeout. The whole firmware loading willl hopefully move into the kernel and the fragile-since-day-one fake async driver-core device dance involving udev can be retired: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=abb139e75c2cdbb955e840d6331cb5863e409d0e --- diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 35263ff13..9bbc8ec8a 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -95,8 +95,9 @@ struct event { size_t devpath_len; const char *devpath_old; dev_t devnum; - bool is_block; int ifindex; + bool is_block; + bool nodelay; }; static inline struct event *node_to_event(struct udev_list_node *node) @@ -438,8 +439,10 @@ static int event_queue_insert(struct udev_device *dev) event->devpath_len = strlen(event->devpath); event->devpath_old = udev_device_get_devpath_old(dev); event->devnum = udev_device_get_devnum(dev); - event->is_block = (strcmp("block", udev_device_get_subsystem(dev)) == 0); + event->is_block = streq("block", udev_device_get_subsystem(dev)); event->ifindex = udev_device_get_ifindex(dev); + if (streq(udev_device_get_subsystem(dev), "firmware")) + event->nodelay = true; udev_queue_export_device_queued(udev_queue_export, dev); log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev), @@ -519,6 +522,10 @@ static bool is_devpath_busy(struct event *event) return true; } + /* allow to bypass the dependency tracking */ + if (event->nodelay) + continue; + /* parent device event found */ if (event->devpath[common] == '/') { event->delaying_seqnum = loop_event->seqnum;