netlink: add net device refcount tracker to struct ethnl_req_info
authorEric Dumazet <edumazet@google.com>
Tue, 7 Dec 2021 01:30:37 +0000 (17:30 -0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 8 Dec 2021 04:44:59 +0000 (20:44 -0800)
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ethtool/netlink.c
net/ethtool/netlink.h

index 38b44c0..eaa50af 100644 (file)
@@ -141,6 +141,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
        }
 
        req_info->dev = dev;
+       netdev_tracker_alloc(dev, &req_info->dev_tracker, GFP_KERNEL);
        req_info->flags = flags;
        return 0;
 }
@@ -399,7 +400,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
                ops->cleanup_data(reply_data);
 
        genlmsg_end(rskb, reply_payload);
-       dev_put(req_info->dev);
+       dev_put_track(req_info->dev, &req_info->dev_tracker);
        kfree(reply_data);
        kfree(req_info);
        return genlmsg_reply(rskb, info);
@@ -411,7 +412,7 @@ err_cleanup:
        if (ops->cleanup_data)
                ops->cleanup_data(reply_data);
 err_dev:
-       dev_put(req_info->dev);
+       dev_put_track(req_info->dev, &req_info->dev_tracker);
        kfree(reply_data);
        kfree(req_info);
        return ret;
@@ -547,7 +548,7 @@ static int ethnl_default_start(struct netlink_callback *cb)
                 * same parser as for non-dump (doit) requests is used, it
                 * would take reference to the device if it finds one
                 */
-               dev_put(req_info->dev);
+               dev_put_track(req_info->dev, &req_info->dev_tracker);
                req_info->dev = NULL;
        }
        if (ret < 0)
@@ -624,6 +625,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
        }
 
        req_info->dev = dev;
+       netdev_tracker_alloc(dev, &req_info->dev_tracker, GFP_KERNEL);
        req_info->flags |= ETHTOOL_FLAG_COMPACT_BITSETS;
 
        ethnl_init_reply_data(reply_data, ops, dev);
index 490598e..a779bbb 100644 (file)
@@ -222,6 +222,7 @@ static inline unsigned int ethnl_reply_header_size(void)
 /**
  * struct ethnl_req_info - base type of request information for GET requests
  * @dev:   network device the request is for (may be null)
+ * @dev_tracker: refcount tracker for @dev reference
  * @flags: request flags common for all request types
  *
  * This is a common base for request specific structures holding data from
@@ -230,6 +231,7 @@ static inline unsigned int ethnl_reply_header_size(void)
  */
 struct ethnl_req_info {
        struct net_device       *dev;
+       netdevice_tracker       dev_tracker;
        u32                     flags;
 };