summaryrefslogtreecommitdiffstats
path: root/net/ethtool
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2021-12-06 17:30:37 -0800
committerJakub Kicinski <kuba@kernel.org>2021-12-07 20:44:59 -0800
commite4b8954074f6d0db01c8c97d338a67f9389c042f (patch)
treec41b7f602f062f079f6422a16ae7c3fb6c2e7c61 /net/ethtool
parentb60645248af3b2485c7695f04e5ecfbc129eb1f7 (diff)
downloadlinux-e4b8954074f6d0db01c8c97d338a67f9389c042f.tar.bz2
netlink: add net device refcount tracker to struct ethnl_req_info
Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ethtool')
-rw-r--r--net/ethtool/netlink.c8
-rw-r--r--net/ethtool/netlink.h2
2 files changed, 7 insertions, 3 deletions
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index 38b44c0291b1..eaa50af074be 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -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);
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index 490598e5eedd..a779bbb0c524 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -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;
};