I'm trying to find a robust way to handle the phrasing of UDev rules and
systemd dependencies about /dev/dri/cardXXX nodes to ensure that several
compositor services running on different graphics cards of a device all can
reliably start up.
First, some basic observations:
* The DRM subsystem in the kernel will automatically acquire DRM master
status on an fd opened against a card, if no other fd open against that card is
already a DRM master.
* DRI cards do have a human-readable identifier -- the "name" field
reported by drmGetVersion() -- which can be used to reliably identify them. But
this name is not exposed as a sysfs attribute on the device. So it's invisible
to UDev rules.
* DRI cards initialize in parallel to each other, so the basic kernel names
such as 'card0', 'card1', and similar are not stable.
On a system with multiple cards with each one used by a separate compositor
application, this makes it a bit difficult to start each compositor only when
its specific card is enumerated in UDev a bit tricky.
* The lack of a sysfs property exposing the drmGetVersion()->name field,
makes phrasing a UDev rule directly such as this impossible:
SUBSYSTEM=="drm", ATTRS{name}=="amd", SYMLINK+="card-amd", TAG+="systemd"
* You could imagine writing a helper program invoked by the UDev rule:
SUBSYSTEM=="drm", PROGRAM="print-dri-symlink-name $env{DEVNAME}" SYMLINK+="%c",
TAG+="systemd"
The "print-dri-symlink-name" program would be responsible for using the libdrm
API to fetch out the card's "name" property.
* But it is not guaranteed that UDev rules fire only once for a given sysfs
device. Which means that the next bullet point applies.
* The UDev helper program temporarily acquires DRM master status because of
that built-in behavior from the DRI subsystem. If you're unlucky, this will
conflict with the compositor's legitimate attempt to become DRM master.
If the systemd .device unit (e.g. dev-dri-card-amd.device) activated by the
initial UDev rule firing is already up and running, and a second UDev rule
instance executes at the same time that a compositor application is just
starting up, there is a small but feasible chance that the UDev helper program
will acquire DRM master rights during exactly the duration that the compositor
is attempting its own initializer. The compositor will therefore be denied DRM
master status, and fail.
I'm not really sure how the race in the final bullet point can be prevented. It
seems to me that the only ironclad way to avoid it would be to perform the UDev
rule matches strictly based on sysfs attributes. Has there ever been any talk
about exporting the DRI card name through sysfs?
On the other hand, maybe I'm approach this problem completely wrongly. Is it a
losing game to try to phrase systemd ordering constraints on /dev/dri cards?
-Matt