Discussion:
[systemd-devel] what's the order in which systemd .device units are created ?
Abder
2021-06-02 12:00:55 UTC
Permalink
Hi,

Even though I've browsed through a lot of resources I haven't found any
satisfying answer to my question. I've been trying to minimize the booting
time in the user land on my embedded board, and when I run the classic
$systemd-analyze plot > plot.svg I saw that there is a non-negligible slot
of time in which all what systemd does is creating device units that were
discovered via udev.

My problem is in the order in which these device units are created,
specially for the block device that contains my rootfs. What I noticed is
that when these device units are created, the one corresponding to my
rootfs blockdev partition is always the last one created, causing the other
services depending on it to wait much more than if the device unit was
created earlier.

So, I would like to know if systemd follows a special order when creating
these units, and if yes, what can I do so the device unit of my rootfs
blockdev partition can be the first one created ?

Any help is greatly appreciated.
Lennart Poettering
2021-06-02 12:36:51 UTC
Permalink
Post by Abder
Hi,
Even though I've browsed through a lot of resources I haven't found any
satisfying answer to my question. I've been trying to minimize the booting
time in the user land on my embedded board, and when I run the classic
$systemd-analyze plot > plot.svg I saw that there is a non-negligible slot
of time in which all what systemd does is creating device units that were
discovered via udev.
My problem is in the order in which these device units are created,
specially for the block device that contains my rootfs. What I noticed is
that when these device units are created, the one corresponding to my
rootfs blockdev partition is always the last one created, causing the other
services depending on it to wait much more than if the device unit was
created earlier.
So, I would like to know if systemd follows a special order when creating
these units, and if yes, what can I do so the device unit of my rootfs
blockdev partition can be the first one created ?
The systemd-udev-trigger.service unit invokes "udevadm trigger" to
trigger all devices that are already discovered by the kernel at that
point. PID 1 listens to that and synthesizes .device units from all
devices popping up. The order in which "udevadm trigger" triggers them
is pretty much the order in which readdir() returns the devices when
iterating through /sys/, i.e. basically undefined.

There's a github issue open somewhere where I proposed adding a new
switch to "udevadm trigger" called --priorize-subsystem=… or so, which
you can use to priorize on or more subsystems: any subsystems listed
that way are triggered first. That way you could do "udevadm trigger
--priorize-subsystem=block" to ensure block devices are triggered
first (in fact, we probably should use this as default once we have
the concept, given that the most relevant devices we wait for at boot
are probably all block device). Would be happy to review/merge a patch
for that.

Note that the order in which devices are triggered does not directly
translate to the order in which devices actually are processed and
make it through udevd and are picked up by PID 1. udevd runs rules for
each device, and if those are slow and take a bit of time, this might
delay delivery of the events to PID 1. However, there's certainly some
relationship here: if certain devices are the ones we start processing
first thy are likely also the devices where we finish processing them
first, even if there's no strict guarantee for that.

Lennart

--
Lennart Poettering, Berlin
Abder
2021-06-02 14:55:31 UTC
Permalink
Post by Lennart Poettering
Post by Abder
Hi,
Even though I've browsed through a lot of resources I haven't found any
satisfying answer to my question. I've been trying to minimize the booting
time in the user land on my embedded board, and when I run the classic
$systemd-analyze plot > plot.svg I saw that there is a non-negligible slot
of time in which all what systemd does is creating device units that were
discovered via udev.
My problem is in the order in which these device units are created,
specially for the block device that contains my rootfs. What I noticed is
that when these device units are created, the one corresponding to my
rootfs blockdev partition is always the last one created, causing the other
services depending on it to wait much more than if the device unit was
created earlier.
So, I would like to know if systemd follows a special order when creating
these units, and if yes, what can I do so the device unit of my rootfs
blockdev partition can be the first one created ?
The systemd-udev-trigger.service unit invokes "udevadm trigger" to
trigger all devices that are already discovered by the kernel at that
point. PID 1 listens to that and synthesizes .device units from all
devices popping up. The order in which "udevadm trigger" triggers them
is pretty much the order in which readdir() returns the devices when
iterating through /sys/, i.e. basically undefined.
There's a github issue open somewhere where I proposed adding a new
switch to "udevadm trigger" called --priorize-subsystem=
 or so, which
you can use to priorize on or more subsystems: any subsystems listed
that way are triggered first. That way you could do "udevadm trigger
--priorize-subsystem=block" to ensure block devices are triggered
first (in fact, we probably should use this as default once we have
the concept, given that the most relevant devices we wait for at boot
are probably all block device). Would be happy to review/merge a patch
for that.
Can't we already achieve this using the udevadm trigger filters
i.e. --subsystem-match= ?
Post by Lennart Poettering
Note that the order in which devices are triggered does not directly
translate to the order in which devices actually are processed and
make it through udevd and are picked up by PID 1. udevd runs rules for
each device, and if those are slow and take a bit of time, this might
delay delivery of the events to PID 1. However, there's certainly some
relationship here: if certain devices are the ones we start processing
first thy are likely also the devices where we finish processing them
first, even if there's no strict guarantee for that.
I also like to mention that even if the block device is triggered earlier
in systemd-udev-trigger.service (using the --subsystem-match= ), sometimes
the creation of the corresponding device unit is delayed. I noticed a delay
of 0.8 to 1.5 seconds between the time systemd-udev-trigger.service became
active and the time systemd started creating .device units.

I'm no expert in systemd and how PID 1 synthesizes the .device units
from udev, but if I understood correctly your suggestion regarding
prioritization, I think the implementation needs to be also on the systemd
side. An example of such implementation can be the definition of a new udev
keyword that one can use inside udev rules to mark devices that need to be
prioritized by systemd.

--
Thank you for your reply, I appreciate it.

Loading...