To ease the code reuse for RSS_CREATE we'll want to prepare struct rss_reply_data for the new context. Unfortunately we can't depend on the exiting scaffolding because the context doesn't exist (ctx=NULL) when we start preparing. Factor out the portion of the context 0 handling responsible for allocation of request memory, so that we can call it directly. Signed-off-by: Jakub Kicinski --- net/ethtool/rss.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c index 3c6a070ef875..07a9d89e1c6b 100644 --- a/net/ethtool/rss.c +++ b/net/ethtool/rss.c @@ -113,21 +113,11 @@ rss_prepare_flow_hash(const struct rss_req_info *req, struct net_device *dev, } static int -rss_prepare_get(const struct rss_req_info *request, struct net_device *dev, - struct rss_reply_data *data, const struct genl_info *info) +rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data) { - struct ethtool_rxfh_param rxfh = {}; - const struct ethtool_ops *ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u32 total_size, indir_bytes; u8 *rss_config; - int ret; - - ops = dev->ethtool_ops; - - ret = ethnl_ops_begin(dev); - if (ret < 0) - return ret; - mutex_lock(&dev->ethtool->rss_lock); data->indir_size = 0; data->hkey_size = 0; @@ -139,16 +129,39 @@ rss_prepare_get(const struct rss_req_info *request, struct net_device *dev, indir_bytes = data->indir_size * sizeof(u32); total_size = indir_bytes + data->hkey_size; rss_config = kzalloc(total_size, GFP_KERNEL); - if (!rss_config) { - ret = -ENOMEM; - goto out_unlock; - } + if (!rss_config) + return -ENOMEM; if (data->indir_size) data->indir_table = (u32 *)rss_config; if (data->hkey_size) data->hkey = rss_config + indir_bytes; + return 0; +} + +static void rss_get_data_free(const struct rss_reply_data *data) +{ + kfree(data->indir_table); +} + +static int +rss_prepare_get(const struct rss_req_info *request, struct net_device *dev, + struct rss_reply_data *data, const struct genl_info *info) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + struct ethtool_rxfh_param rxfh = {}; + int ret; + + ret = ethnl_ops_begin(dev); + if (ret < 0) + return ret; + mutex_lock(&dev->ethtool->rss_lock); + + ret = rss_get_data_alloc(dev, data); + if (ret) + goto out_unlock; + rxfh.indir_size = data->indir_size; rxfh.indir = data->indir_table; rxfh.key_size = data->hkey_size; @@ -318,7 +331,7 @@ static void rss_cleanup_data(struct ethnl_reply_data *reply_base) { const struct rss_reply_data *data = RSS_REPDATA(reply_base); - kfree(data->indir_table); + rss_get_data_free(data); } struct rss_nl_dump_ctx { -- 2.50.1