udev-builtin-path_id: emit 'sf-<N>' token for auxiliary sub-functions

Some drivers expose sub-functions (SFs) of a PCI Physical or Virtual
Function as auxiliary devices that carry a stable 'sfnum' sysfs
attribute — the user-defined sub-function number (e.g. the value
passed to "devlink port add ... sfnum N"). The SF's leaf devices
(uverbs, infiniband, net, ...) sit below this aux device in sysfs:

  /sys/devices/.../<PF or VF BDF>/<sf aux>/.../<leaf>

Currently path_id walks straight past the aux device, so all leaf
devices below an SF end up sharing ID_PATH=pci-<BDF> with their
parent PF or VF. For uverbs this causes a /dev/infiniband/by-path/
symlink collision, and for any other consumer of ID_PATH/ID_PATH_TAG
it makes PF and SF (or VF and VF-SF) indistinguishable.

Recognise the 'auxiliary' subsystem in path_id's walk: when the aux
device exposes 'sfnum', prepend an 'sf-<N>' token; otherwise leave
it untokenised. The result for an SF whose parent PF is at PCI
0000:c1:00.0 and which was added with "sfnum 88" is:

  ID_PATH=pci-0000:c1:00.0-sf-88
  ID_PATH_TAG=pci-0000_c1_00_0-sf-88

This is parallel to how net_id's NAMING_SUBFUNC scheme appends 'S<N>'
on top of the PF base name. Aux devices without 'sfnum' keep the
pre-patch behaviour: the walk skips over them with no token. Existing
ID_PATH values for PF and VF leaf devices are therefore unchanged,
the change is purely additive, and there is no need to gate it behind
a naming scheme (path_id itself is unversioned).

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Jiri Pirko
2026-05-19 14:39:20 +02:00
parent 86e74db277
commit 477f84cf91
+12
View File
@@ -711,6 +711,18 @@ static int builtin_path_id(UdevEvent *event, int argc, char *argv[]) {
path_prepend(&path, "serio-%s", sysnum);
parent = skip_subsystem(parent, "serio");
}
} else if (device_in_subsystem(parent, "auxiliary") > 0) {
unsigned sfnum;
/* sfnum is the user-defined sub-function number (devlink port add ...
* sfnum N). Prepend it so an SF leaf device gets an ID_PATH distinct
* from its parent PF/VF; aux devices without 'sfnum' emit no token to
* preserve pre-patch ID_PATH values. */
if (device_get_sysattr_unsigned(parent, "sfnum", &sfnum) >= 0) {
path_prepend(&path, "sf-%u", sfnum);
if (compat_path)
path_prepend(&compat_path, "sf-%u", sfnum);
}
} else if (device_in_subsystem(parent, "pci") > 0) {
path_prepend(&path, "pci-%s", sysname);
if (compat_path)