diff mbox series

[net-next,v4,5/6] devlink: hold a reference to the netdevice around ethtool compat

Message ID 20190226033407.32625-6-jakub.kicinski@netronome.com
State Accepted
Delegated to: David Miller
Headers show
Series devlink: make ethtool compat reliable | expand

Commit Message

Jakub Kicinski Feb. 26, 2019, 3:34 a.m. UTC
When ethtool is calling into devlink compat code make sure we have
a reference on the netdevice on which the operation was invoked.

v3: move the hold/lock logic into devlink_compat_* functions (Florian)

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 net/core/devlink.c | 13 +++++++++++++
 net/core/ethtool.c | 13 ++-----------
 2 files changed, 15 insertions(+), 11 deletions(-)

Comments

Florian Fainelli Feb. 26, 2019, 4:26 a.m. UTC | #1
On 2/25/2019 7:34 PM, Jakub Kicinski wrote:
> When ethtool is calling into devlink compat code make sure we have
> a reference on the netdevice on which the operation was invoked.
> 
> v3: move the hold/lock logic into devlink_compat_* functions (Florian)
> 
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Jiri Pirko Feb. 26, 2019, 8:57 a.m. UTC | #2
Tue, Feb 26, 2019 at 04:34:06AM CET, jakub.kicinski@netronome.com wrote:
>When ethtool is calling into devlink compat code make sure we have
>a reference on the netdevice on which the operation was invoked.
>
>v3: move the hold/lock logic into devlink_compat_* functions (Florian)
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>
diff mbox series

Patch

diff --git a/net/core/devlink.c b/net/core/devlink.c
index 24bfbd2d71e7..ecff6e63bc4d 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -6430,6 +6430,9 @@  void devlink_compat_running_version(struct net_device *dev,
 {
 	struct devlink *devlink;
 
+	dev_hold(dev);
+	rtnl_unlock();
+
 	mutex_lock(&devlink_mutex);
 	devlink = netdev_to_devlink(dev);
 	if (!devlink || !devlink->ops || !devlink->ops->info_get)
@@ -6440,6 +6443,9 @@  void devlink_compat_running_version(struct net_device *dev,
 	mutex_unlock(&devlink->lock);
 unlock_list:
 	mutex_unlock(&devlink_mutex);
+
+	rtnl_lock();
+	dev_put(dev);
 }
 
 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
@@ -6447,6 +6453,9 @@  int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
 	struct devlink *devlink;
 	int ret = -EOPNOTSUPP;
 
+	dev_hold(dev);
+	rtnl_unlock();
+
 	mutex_lock(&devlink_mutex);
 	devlink = netdev_to_devlink(dev);
 	if (!devlink || !devlink->ops || !devlink->ops->flash_update)
@@ -6457,6 +6466,10 @@  int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
 	mutex_unlock(&devlink->lock);
 unlock_list:
 	mutex_unlock(&devlink_mutex);
+
+	rtnl_lock();
+	dev_put(dev);
+
 	return ret;
 }
 
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 1320e8dce559..47558ffae423 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -805,11 +805,9 @@  static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
 	if (ops->get_eeprom_len)
 		info.eedump_len = ops->get_eeprom_len(dev);
 
-	rtnl_unlock();
 	if (!info.fw_version[0])
 		devlink_compat_running_version(dev, info.fw_version,
 					       sizeof(info.fw_version));
-	rtnl_lock();
 
 	if (copy_to_user(useraddr, &info, sizeof(info)))
 		return -EFAULT;
@@ -2040,15 +2038,8 @@  static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
 		return -EFAULT;
 	efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
 
-	if (!dev->ethtool_ops->flash_device) {
-		int ret;
-
-		rtnl_unlock();
-		ret = devlink_compat_flash_update(dev, efl.data);
-		rtnl_lock();
-
-		return ret;
-	}
+	if (!dev->ethtool_ops->flash_device)
+		return devlink_compat_flash_update(dev, efl.data);
 
 	return dev->ethtool_ops->flash_device(dev, &efl);
 }