Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ethtool: rss: factor out allocating memory for response

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>

+30 -17
+30 -17
net/ethtool/rss.c
··· 113 113 } 114 114 115 115 static int 116 - rss_prepare_get(const struct rss_req_info *request, struct net_device *dev, 117 - struct rss_reply_data *data, const struct genl_info *info) 116 + rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data) 118 117 { 119 - struct ethtool_rxfh_param rxfh = {}; 120 - const struct ethtool_ops *ops; 118 + const struct ethtool_ops *ops = dev->ethtool_ops; 121 119 u32 total_size, indir_bytes; 122 120 u8 *rss_config; 123 - int ret; 124 - 125 - ops = dev->ethtool_ops; 126 - 127 - ret = ethnl_ops_begin(dev); 128 - if (ret < 0) 129 - return ret; 130 - mutex_lock(&dev->ethtool->rss_lock); 131 121 132 122 data->indir_size = 0; 133 123 data->hkey_size = 0; ··· 129 139 indir_bytes = data->indir_size * sizeof(u32); 130 140 total_size = indir_bytes + data->hkey_size; 131 141 rss_config = kzalloc(total_size, GFP_KERNEL); 132 - if (!rss_config) { 133 - ret = -ENOMEM; 134 - goto out_unlock; 135 - } 142 + if (!rss_config) 143 + return -ENOMEM; 136 144 137 145 if (data->indir_size) 138 146 data->indir_table = (u32 *)rss_config; 139 147 if (data->hkey_size) 140 148 data->hkey = rss_config + indir_bytes; 149 + 150 + return 0; 151 + } 152 + 153 + static void rss_get_data_free(const struct rss_reply_data *data) 154 + { 155 + kfree(data->indir_table); 156 + } 157 + 158 + static int 159 + rss_prepare_get(const struct rss_req_info *request, struct net_device *dev, 160 + struct rss_reply_data *data, const struct genl_info *info) 161 + { 162 + const struct ethtool_ops *ops = dev->ethtool_ops; 163 + struct ethtool_rxfh_param rxfh = {}; 164 + int ret; 165 + 166 + ret = ethnl_ops_begin(dev); 167 + if (ret < 0) 168 + return ret; 169 + mutex_lock(&dev->ethtool->rss_lock); 170 + 171 + ret = rss_get_data_alloc(dev, data); 172 + if (ret) 173 + goto out_unlock; 141 174 142 175 rxfh.indir_size = data->indir_size; 143 176 rxfh.indir = data->indir_table; ··· 331 318 { 332 319 const struct rss_reply_data *data = RSS_REPDATA(reply_base); 333 320 334 - kfree(data->indir_table); 321 + rss_get_data_free(data); 335 322 } 336 323 337 324 struct rss_nl_dump_ctx {