net-sysfs: call dev_hold if kobject_init_and_add success [Linux 3.16.72]

This Linux kernel change "net-sysfs: call dev_hold if kobject_init_and_add success" is included in the Linux 3.16.72 release. This change is authored by YueHaibing <yuehaibing [at] huawei.com> on Tue Mar 19 10:16:53 2019 +0800. The commit for this change in Linux stable tree is 1b75034 (patch) which is from upstream commit a3e23f7. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream a3e23f7.

net-sysfs: call dev_hold if kobject_init_and_add success

commit a3e23f719f5c4a38ffb3d30c8d7632a4ed8ccd9e upstream.

In netdev_queue_add_kobject and rx_queue_add_kobject,
if sysfs_create_group failed, kobject_put will call
netdev_queue_release to decrease dev refcont, however
dev_hold has not be called. So we will see this while
unregistering dev:

unregister_netdevice: waiting for bcsh0 to become free. Usage count = -1

Reported-by: Hulk Robot <[email protected]>
Fixes: d0d668371679 ("net: don't decrement kobj reference count on init failure")
Signed-off-by: YueHaibing <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>

There are 6 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/core/net-sysfs.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index cd332d0..7550d09 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -788,6 +788,8 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
    if (error)
        return error;

+   dev_hold(queue->dev);
+
    if (net->sysfs_rx_queue_group) {
        error = sysfs_create_group(kobj, net->sysfs_rx_queue_group);
        if (error) {
@@ -797,7 +799,6 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
    }

    kobject_uevent(kobj, KOBJ_ADD);
-   dev_hold(queue->dev);

    return error;
 }
@@ -1146,6 +1147,8 @@ static int netdev_queue_add_kobject(struct net_device *net, int index)
    if (error)
        return error;

+   dev_hold(queue->dev);
+
 #ifdef CONFIG_BQL
    error = sysfs_create_group(kobj, &dql_group);
    if (error) {
@@ -1155,7 +1158,6 @@ static int netdev_queue_add_kobject(struct net_device *net, int index)
 #endif

    kobject_uevent(kobj, KOBJ_ADD);
-   dev_hold(queue->dev);

    return 0;
 }

Leave a Reply

Your email address will not be published. Required fields are marked *