diff options
| -rw-r--r-- | net/ethtool/common.c | 2 | ||||
| -rw-r--r-- | net/ethtool/ioctl.c | 11 | ||||
| -rw-r--r-- | net/ethtool/rss.c | 23 |
3 files changed, 27 insertions, 9 deletions
diff --git a/net/ethtool/common.c b/net/ethtool/common.c index eb253e0fd61b..d62dc56f2f5b 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -707,7 +707,9 @@ static u32 ethtool_get_max_rxfh_channel(struct net_device *dev) if (!rxfh.indir) return U32_MAX; + mutex_lock(&dev->ethtool->rss_lock); ret = dev->ethtool_ops->get_rxfh(dev, &rxfh); + mutex_unlock(&dev->ethtool->rss_lock); if (ret) { current_max = U32_MAX; goto out_free; diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index df376628ba19..b6d96e562c9a 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1079,16 +1079,17 @@ ethtool_set_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr) !ops->rxfh_per_ctx_fields) return -EINVAL; + mutex_lock(&dev->ethtool->rss_lock); if (ops->get_rxfh) { struct ethtool_rxfh_param rxfh = {}; rc = ops->get_rxfh(dev, &rxfh); if (rc) - return rc; + goto exit_unlock; rc = ethtool_check_xfrm_rxfh(rxfh.input_xfrm, info.data); if (rc) - return rc; + goto exit_unlock; } fields.data = info.data; @@ -1096,8 +1097,8 @@ ethtool_set_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr) if (info.flow_type & FLOW_RSS) fields.rss_context = info.rss_context; - mutex_lock(&dev->ethtool->rss_lock); rc = ops->set_rxfh_fields(dev, &fields, NULL); +exit_unlock: mutex_unlock(&dev->ethtool->rss_lock); return rc; } @@ -1274,7 +1275,9 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, if (!rxfh.indir) return -ENOMEM; + mutex_lock(&dev->ethtool->rss_lock); ret = dev->ethtool_ops->get_rxfh(dev, &rxfh); + mutex_unlock(&dev->ethtool->rss_lock); if (ret) goto out; if (copy_to_user(useraddr + @@ -1413,6 +1416,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev, if (user_key_size) rxfh_dev.key = rss_config + indir_bytes; + mutex_lock(&dev->ethtool->rss_lock); if (rxfh.rss_context) { ctx = xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context); if (!ctx) { @@ -1458,6 +1462,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev, ret = -EFAULT; } out: + mutex_unlock(&dev->ethtool->rss_lock); kfree(rss_config); return ret; diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c index 3adddca7e215..e717f23cbc10 100644 --- a/net/ethtool/rss.c +++ b/net/ethtool/rss.c @@ -139,6 +139,15 @@ rss_prepare_ctx(const struct rss_req_info *request, struct net_device *dev, } static int +rss_prepare(const struct rss_req_info *request, struct net_device *dev, + struct rss_reply_data *data, const struct genl_info *info) +{ + if (request->rss_context) + return rss_prepare_ctx(request, dev, data, info); + return rss_prepare_get(request, dev, data, info); +} + +static int rss_prepare_data(const struct ethnl_req_info *req_base, struct ethnl_reply_data *reply_base, const struct genl_info *info) @@ -147,20 +156,22 @@ rss_prepare_data(const struct ethnl_req_info *req_base, struct rss_req_info *request = RSS_REQINFO(req_base); struct net_device *dev = reply_base->dev; const struct ethtool_ops *ops; + int ret; ops = dev->ethtool_ops; if (!ops->get_rxfh) return -EOPNOTSUPP; /* Some drivers don't handle rss_context */ - if (request->rss_context) { - if (!ops->cap_rss_ctx_supported && !ops->create_rxfh_context) - return -EOPNOTSUPP; + if (request->rss_context && + !ops->cap_rss_ctx_supported && !ops->create_rxfh_context) + return -EOPNOTSUPP; - return rss_prepare_ctx(request, dev, data, info); - } + mutex_lock(&dev->ethtool->rss_lock); + ret = rss_prepare(request, dev, data, info); + mutex_unlock(&dev->ethtool->rss_lock); - return rss_prepare_get(request, dev, data, info); + return ret; } static int |
