Commit a0bfd643 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'ethtool-rss-fix-a-handful-of-small-bugs'

Jakub Kicinski says:

====================
ethtool: rss: fix a handful of small bugs

Fix a handful of small bugs in the ethtool Netlink RSS code.
====================

Link: https://patch.msgid.link/20260522230647.1705600-1-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2e357f00 32a9ecde
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -134,7 +134,6 @@ rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data)
	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;
@@ -170,8 +169,10 @@ rss_prepare_get(const struct rss_req_info *request, struct net_device *dev,
	rxfh.key = data->hkey;

	ret = ops->get_rxfh(dev, &rxfh);
	if (ret)
	if (ret) {
		rss_get_data_free(data);
		goto out_unlock;
	}

	data->hfunc = rxfh.hfunc;
	data->input_xfrm = rxfh.input_xfrm;
@@ -686,7 +687,7 @@ rss_set_prep_indir(struct net_device *dev, struct genl_info *info,
				ethtool_rxfh_indir_default(i, num_rx_rings);
	}

	*mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size);
	*mod |= memcmp(rxfh->indir, data->indir_table, alloc_size);

	return user_size;

@@ -981,11 +982,17 @@ ethnl_rss_create_validate(struct net_device *dev, struct genl_info *info)
}

static void
ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
ethnl_rss_create_send_ntf(const struct sk_buff *rsp, struct net_device *dev)
{
	struct nlmsghdr *nlh = (void *)rsp->data;
	struct genlmsghdr *genl_hdr;
	struct nlmsghdr *nlh;
	struct sk_buff *ntf;

	ntf = skb_copy_expand(rsp, 0, 0, GFP_KERNEL);
	if (!ntf)
		return;

	nlh = nlmsg_hdr(ntf);
	/* Convert the reply into a notification */
	nlh->nlmsg_pid = 0;
	nlh->nlmsg_seq = ethnl_bcast_seq_next();
@@ -993,7 +1000,7 @@ ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
	genl_hdr = nlmsg_data(nlh);
	genl_hdr->cmd =	ETHTOOL_MSG_RSS_CREATE_NTF;

	ethnl_multicast(rsp, dev);
	ethnl_multicast(ntf, dev);
}

int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
@@ -1099,17 +1106,13 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
	ntf_fail |= rss_fill_reply(rsp, &req.base, &data.base);
	if (WARN_ON(!hdr || ntf_fail)) {
		ret = -EMSGSIZE;
		goto exit_unlock;
		goto err_remove_ctx;
	}

	genlmsg_end(rsp, hdr);

	/* Use the same skb for the response and the notification,
	 * genlmsg_reply() will copy the skb if it has elevated user count.
	 */
	skb_get(rsp);
	ret = genlmsg_reply(rsp, info);
	ethnl_rss_create_send_ntf(rsp, dev);
	ret = genlmsg_reply(rsp, info);
	rsp = NULL;

exit_unlock:
@@ -1131,6 +1134,10 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
	nlmsg_free(rsp);
	return ret;

err_remove_ctx:
	if (ops->remove_rxfh_context(dev, ctx, req.rss_context, NULL))
		/* leave the context on failure, like ethnl_rss_delete_doit() */
		goto exit_unlock;
err_ctx_id_free:
	xa_erase(&dev->ethtool->rss_ctx, req.rss_context);
err_unlock_free_ctx:
@@ -1168,8 +1175,10 @@ int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info)
	dev = req.dev;
	ops = dev->ethtool_ops;

	if (!ops->create_rxfh_context)
	if (!ops->create_rxfh_context) {
		ret = -EOPNOTSUPP;
		goto exit_free_dev;
	}

	rtnl_lock();
	netdev_lock_ops(dev);