Skip to content

Commit e020ff6

Browse files
Saravana Kannangregkh
authored andcommitted
driver core: Fix device link device name collision
The device link device's name was of the form: <supplier-dev-name>--<consumer-dev-name> This can cause name collision as reported here [1] as device names are not globally unique. Since device names have to be unique within the bus/class, add the bus/class name as a prefix to the device names used to construct the device link device name. So the devuce link device's name will be of the form: <supplier-bus-name>:<supplier-dev-name>--<consumer-bus-name>:<consumer-dev-name> [1] - https://lore.kernel.org/lkml/[email protected]/ Fixes: 287905e ("driver core: Expose device link details in sysfs") Cc: [email protected] Reported-by: Michael Walle <[email protected]> Tested-by: Michael Walle <[email protected]> Signed-off-by: Saravana Kannan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3d1cf43 commit e020ff6

File tree

5 files changed

+35
-18
lines changed

5 files changed

+35
-18
lines changed

Documentation/ABI/testing/sysfs-class-devlink

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Description:
55
Provide a place in sysfs for the device link objects in the
66
kernel at any given time. The name of a device link directory,
77
denoted as ... above, is of the form <supplier>--<consumer>
8-
where <supplier> is the supplier device name and <consumer> is
9-
the consumer device name.
8+
where <supplier> is the supplier bus:device name and <consumer>
9+
is the consumer bus:device name.
1010

1111
What: /sys/class/devlink/.../auto_remove_on
1212
Date: May 2020

Documentation/ABI/testing/sysfs-devices-consumer

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <[email protected]>
44
Description:
55
The /sys/devices/.../consumer:<consumer> are symlinks to device
66
links where this device is the supplier. <consumer> denotes the
7-
name of the consumer in that device link. There can be zero or
8-
more of these symlinks for a given device.
7+
name of the consumer in that device link and is of the form
8+
bus:device name. There can be zero or more of these symlinks
9+
for a given device.

Documentation/ABI/testing/sysfs-devices-supplier

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <[email protected]>
44
Description:
55
The /sys/devices/.../supplier:<supplier> are symlinks to device
66
links where this device is the consumer. <supplier> denotes the
7-
name of the supplier in that device link. There can be zero or
8-
more of these symlinks for a given device.
7+
name of the supplier in that device link and is of the form
8+
bus:device name. There can be zero or more of these symlinks
9+
for a given device.

drivers/base/core.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,9 @@ static int devlink_add_symlinks(struct device *dev,
471471
struct device *con = link->consumer;
472472
char *buf;
473473

474-
len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
474+
len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
475+
strlen(dev_bus_name(con)) + strlen(dev_name(con)));
476+
len += strlen(":");
475477
len += strlen("supplier:") + 1;
476478
buf = kzalloc(len, GFP_KERNEL);
477479
if (!buf)
@@ -485,20 +487,20 @@ static int devlink_add_symlinks(struct device *dev,
485487
if (ret)
486488
goto err_con;
487489

488-
snprintf(buf, len, "consumer:%s", dev_name(con));
490+
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
489491
ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf);
490492
if (ret)
491493
goto err_con_dev;
492494

493-
snprintf(buf, len, "supplier:%s", dev_name(sup));
495+
snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
494496
ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf);
495497
if (ret)
496498
goto err_sup_dev;
497499

498500
goto out;
499501

500502
err_sup_dev:
501-
snprintf(buf, len, "consumer:%s", dev_name(con));
503+
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
502504
sysfs_remove_link(&sup->kobj, buf);
503505
err_con_dev:
504506
sysfs_remove_link(&link->link_dev.kobj, "consumer");
@@ -521,17 +523,19 @@ static void devlink_remove_symlinks(struct device *dev,
521523
sysfs_remove_link(&link->link_dev.kobj, "consumer");
522524
sysfs_remove_link(&link->link_dev.kobj, "supplier");
523525

524-
len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
526+
len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
527+
strlen(dev_bus_name(con)) + strlen(dev_name(con)));
528+
len += strlen(":");
525529
len += strlen("supplier:") + 1;
526530
buf = kzalloc(len, GFP_KERNEL);
527531
if (!buf) {
528532
WARN(1, "Unable to properly free device link symlinks!\n");
529533
return;
530534
}
531535

532-
snprintf(buf, len, "supplier:%s", dev_name(sup));
536+
snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
533537
sysfs_remove_link(&con->kobj, buf);
534-
snprintf(buf, len, "consumer:%s", dev_name(con));
538+
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
535539
sysfs_remove_link(&sup->kobj, buf);
536540
kfree(buf);
537541
}
@@ -752,8 +756,9 @@ struct device_link *device_link_add(struct device *consumer,
752756

753757
link->link_dev.class = &devlink_class;
754758
device_set_pm_not_required(&link->link_dev);
755-
dev_set_name(&link->link_dev, "%s--%s",
756-
dev_name(supplier), dev_name(consumer));
759+
dev_set_name(&link->link_dev, "%s:%s--%s:%s",
760+
dev_bus_name(supplier), dev_name(supplier),
761+
dev_bus_name(consumer), dev_name(consumer));
757762
if (device_register(&link->link_dev)) {
758763
put_device(consumer);
759764
put_device(supplier);
@@ -1823,9 +1828,7 @@ const char *dev_driver_string(const struct device *dev)
18231828
* never change once they are set, so they don't need special care.
18241829
*/
18251830
drv = READ_ONCE(dev->driver);
1826-
return drv ? drv->name :
1827-
(dev->bus ? dev->bus->name :
1828-
(dev->class ? dev->class->name : ""));
1831+
return drv ? drv->name : dev_bus_name(dev);
18291832
}
18301833
EXPORT_SYMBOL(dev_driver_string);
18311834

include/linux/device.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,18 @@ static inline const char *dev_name(const struct device *dev)
609609
return kobject_name(&dev->kobj);
610610
}
611611

612+
/**
613+
* dev_bus_name - Return a device's bus/class name, if at all possible
614+
* @dev: struct device to get the bus/class name of
615+
*
616+
* Will return the name of the bus/class the device is attached to. If it is
617+
* not attached to a bus/class, an empty string will be returned.
618+
*/
619+
static inline const char *dev_bus_name(const struct device *dev)
620+
{
621+
return dev->bus ? dev->bus->name : (dev->class ? dev->class->name : "");
622+
}
623+
612624
__printf(2, 3) int dev_set_name(struct device *dev, const char *name, ...);
613625

614626
#ifdef CONFIG_NUMA

0 commit comments

Comments
 (0)