summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/ethtool/ioctl.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index c34bac7bffd8..ce7d720b3c79 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1334,9 +1334,11 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
}
rxfh_dev.hfunc = ETH_RSS_HASH_NO_CHANGE;
+
+ mutex_lock(&dev->ethtool->rss_lock);
ret = ops->set_rxfh(dev, &rxfh_dev, extack);
if (ret)
- goto out;
+ goto out_unlock;
/* indicate whether rxfh was set to default */
if (user_size == 0)
@@ -1344,6 +1346,8 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
else
dev->priv_flags |= IFF_RXFH_CONFIGURED;
+out_unlock:
+ mutex_unlock(&dev->ethtool->rss_lock);
out:
kfree(rxfh_dev.indir);
return ret;
@@ -1500,7 +1504,6 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
struct netlink_ext_ack *extack = NULL;
struct ethtool_rxnfc rx_rings;
struct ethtool_rxfh rxfh;
- bool locked = false; /* dev->ethtool->rss_lock taken */
bool create = false;
bool mod = false;
u8 *rss_config;
@@ -1570,7 +1573,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
rx_rings.cmd = ETHTOOL_GRXRINGS;
ret = ops->get_rxnfc(dev, &rx_rings, NULL);
if (ret)
- goto out;
+ goto out_free;
/* rxfh.indir_size == 0 means reset the indir table to default (master
* context) or delete the context (other RSS contexts).
@@ -1586,7 +1589,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
&rx_rings,
rxfh.indir_size);
if (ret)
- goto out;
+ goto out_free;
} else if (rxfh.indir_size == 0) {
if (rxfh.rss_context == 0) {
u32 *indir;
@@ -1608,30 +1611,27 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
useraddr + rss_cfg_offset + user_indir_len,
rxfh.key_size)) {
ret = -EFAULT;
- goto out;
+ goto out_free;
}
}
- if (rxfh.rss_context) {
- mutex_lock(&dev->ethtool->rss_lock);
- locked = true;
- }
+ mutex_lock(&dev->ethtool->rss_lock);
if (rxfh.rss_context && rxfh_dev.rss_delete) {
ret = ethtool_check_rss_ctx_busy(dev, rxfh.rss_context);
if (ret)
- goto out;
+ goto out_unlock;
}
if (create) {
if (rxfh_dev.rss_delete) {
ret = -EINVAL;
- goto out;
+ goto out_unlock;
}
ctx = ethtool_rxfh_ctx_alloc(ops, dev_indir_size, dev_key_size);
if (!ctx) {
ret = -ENOMEM;
- goto out;
+ goto out_unlock;
}
if (ops->create_rxfh_context) {
@@ -1644,7 +1644,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
GFP_KERNEL_ACCOUNT);
if (ret < 0) {
kfree(ctx);
- goto out;
+ goto out_unlock;
}
WARN_ON(!ctx_id); /* can't happen */
rxfh.rss_context = ctx_id;
@@ -1653,7 +1653,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
ctx = xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context);
if (!ctx) {
ret = -ENOENT;
- goto out;
+ goto out_unlock;
}
}
rxfh_dev.hfunc = rxfh.hfunc;
@@ -1687,7 +1687,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
kfree(ctx);
}
- goto out;
+ goto out_unlock;
}
mod = !create && !rxfh_dev.rss_delete;
@@ -1708,13 +1708,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
if (WARN_ON(xa_load(&dev->ethtool->rss_ctx, rxfh_dev.rss_context))) {
/* context ID reused, our tracking is screwed */
kfree(ctx);
- goto out;
+ goto out_unlock;
}
/* Allocate the exact ID the driver gave us */
if (xa_is_err(xa_store(&dev->ethtool->rss_ctx, rxfh_dev.rss_context,
ctx, GFP_KERNEL))) {
kfree(ctx);
- goto out;
+ goto out_unlock;
}
/* Fetch the defaults for the old API, in the new API drivers
@@ -1730,7 +1730,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
if (WARN_ON(ret)) {
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
kfree(ctx);
- goto out;
+ goto out_unlock;
}
}
if (rxfh_dev.rss_delete) {
@@ -1755,9 +1755,9 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
ctx->input_xfrm = rxfh_dev.input_xfrm;
}
-out:
- if (locked)
- mutex_unlock(&dev->ethtool->rss_lock);
+out_unlock:
+ mutex_unlock(&dev->ethtool->rss_lock);
+out_free:
kfree(rss_config);
if (mod)
ethtool_rss_notify(dev, rxfh.rss_context);