From: Jakub Kicinski Date: Tue, 26 Feb 2019 03:34:06 +0000 (-0800) Subject: devlink: hold a reference to the netdevice around ethtool compat X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=1b45ff6c17f1d07c496b08dd602a4aff8fe40848;p=openwrt%2Fstaging%2Fblogic.git devlink: hold a reference to the netdevice around ethtool compat 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 Reviewed-by: Florian Fainelli Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- 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); }