On Sat, Jan 9, 2021 at 8:49 AM Michael Walle michael@walle.cc wrote:
Am 2021-01-08 18:22, schrieb Saravana Kannan:
On Fri, Jan 8, 2021 at 12:16 AM Michael Walle michael@walle.cc wrote:
Am 2021-01-08 02:24, schrieb Saravana Kannan:
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/20201229033440.32142-1-michael@walle.cc/
Cc: stable@vger.kernel.org Fixes: 287905e68dd2 ("driver core: Expose device link details in sysfs") Reported-by: Michael Walle michael@walle.cc Signed-off-by: Saravana Kannan saravanak@google.com
[..]
The changes are missing for the error path and devlink_remove_symlinks(), right?
Removing symlinks doesn't need the name. Just needs the "handle". So we are good there.
I don't get it. What is the "handle"? Without the patch below kernfs_remove_by_name() in sysfs_remove_link will return -ENOENT. With the patch it will return 0.
And even if it would work, how is this even logical:
Ah sorry, I confused it with removing device attrs. I need to fix up the symlink remove path.
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf); if (ret) goto err_con_dev; snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf); if (ret) goto err_sup_dev;
[..] err_sup_dev: snprintf(buf, len, "consumer:%s", dev_name(con)); sysfs_remove_link(&sup->kobj, buf);
You call sysfs_create_link("consumer:bus_name:dev_name") but the corresponding rollback is sysfs_remove_link("consumer:dev_name"), that is super confusing.
diff --git a/drivers/base/core.c b/drivers/base/core.c index 4140a69dfe18..385e16d92874 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -485,7 +485,7 @@ static int devlink_add_symlinks(struct device *dev, goto out;
err_sup_dev:
snprintf(buf, len, "consumer:%s", dev_name(con));
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con),
dev_name(con)); sysfs_remove_link(&sup->kobj, buf); err_con_dev: sysfs_remove_link(&link->link_dev.kobj, "consumer"); @@ -508,7 +508,9 @@ static void devlink_remove_symlinks(struct device *dev, sysfs_remove_link(&link->link_dev.kobj, "consumer"); sysfs_remove_link(&link->link_dev.kobj, "supplier");
len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
strlen(dev_bus_name(con)) + strlen(dev_name(con)));
len += strlen(":"); len += strlen("supplier:") + 1; buf = kzalloc(len, GFP_KERNEL); if (!buf) {
@@ -516,9 +518,9 @@ static void devlink_remove_symlinks(struct device *dev, return; }
snprintf(buf, len, "supplier:%s", dev_name(sup));
snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup),
dev_name(sup)); sysfs_remove_link(&con->kobj, buf);
snprintf(buf, len, "consumer:%s", dev_name(con));
snprintf(buf, len, "consumer:%s:%s", dev_bus_name(sup),
dev_name(con));
Ah I completely skimmed over this code thinking it was code from my patch. Like I said, I was struggling with the length of the email due to the logs. Anyway, I'll fix up the remove symlink path too. Thanks for catching that.
btw this should be dev_bus_name(con).
sysfs_remove_link(&sup->kobj, buf); kfree(buf);
}
With these changes:
Tested-by: Michael Walle michael@walle.cc
Greg,
I think it's good to pick up this version if you don't see any issues.
Why so fast?
Sorry, didn't mean to rush. I was just trying to say I wasn't planning on a v4 because I thought your Tested-by was for my unchanged v4, but clearly I need to send a v4.
-Saravana