]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ethtool: rss: factor out allocating memory for response
authorJakub Kicinski <kuba@kernel.org>
Thu, 17 Jul 2025 23:43:38 +0000 (16:43 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 22 Jul 2025 01:20:19 +0000 (18:20 -0700)
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.

Link: https://patch.msgid.link/20250717234343.2328602-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ethtool/rss.c

index 3c6a070ef875871da468c14da599a6c5c0261976..07a9d89e1c6b012a40a656c0c32bf67295174b0a 100644 (file)
@@ -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 {