Commit 32ad1f7a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

net: provide pending ring configuration in net_device



Record the pending configuration in net_device struct.
ethtool core duplicates the current config and the specific
handlers (for now just ringparam) can modify it.

Reviewed-by: default avatarMichael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20250119020518.1962249-4-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 743dea74
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2413,6 +2413,12 @@ struct net_device {

	/** @cfg: net_device queue-related configuration */
	struct netdev_config	*cfg;
	/**
	 * @cfg_pending: same as @cfg but when device is being actively
	 *	reconfigured includes any changes to the configuration
	 *	requested by the user, but which may or may not be rejected.
	 */
	struct netdev_config	*cfg_pending;
	struct ethtool_netdev_state *ethtool;

	/* protected by rtnl_lock */
+2 −0
Original line number Diff line number Diff line
@@ -11546,6 +11546,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
	dev->cfg = kzalloc(sizeof(*dev->cfg), GFP_KERNEL_ACCOUNT);
	if (!dev->cfg)
		goto free_all;
	dev->cfg_pending = dev->cfg;

	napi_config_sz = array_size(maxqs, sizeof(*dev->napi_config));
	dev->napi_config = kvzalloc(napi_config_sz, GFP_KERNEL_ACCOUNT);
@@ -11615,6 +11616,7 @@ void free_netdev(struct net_device *dev)
		return;
	}

	WARN_ON(dev->cfg != dev->cfg_pending);
	kfree(dev->cfg);
	kfree(dev->ethtool);
	netif_free_tx_queues(dev);
+18 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only

#include <net/netdev_queues.h>
#include <net/sock.h>
#include <linux/ethtool_netlink.h>
#include <linux/phy_link_topology.h>
@@ -692,19 +693,33 @@ static int ethnl_default_set_doit(struct sk_buff *skb, struct genl_info *info)
	dev = req_info.dev;

	rtnl_lock();
	dev->cfg_pending = kmemdup(dev->cfg, sizeof(*dev->cfg),
				   GFP_KERNEL_ACCOUNT);
	if (!dev->cfg_pending) {
		ret = -ENOMEM;
		goto out_tie_cfg;
	}

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto out_rtnl;
		goto out_free_cfg;

	ret = ops->set(&req_info, info);
	if (ret <= 0)
	if (ret < 0)
		goto out_ops;

	swap(dev->cfg, dev->cfg_pending);
	if (!ret)
		goto out_ops;
	ethtool_notify(dev, ops->set_ntf_cmd, NULL);

	ret = 0;
out_ops:
	ethnl_ops_complete(dev);
out_rtnl:
out_free_cfg:
	kfree(dev->cfg_pending);
out_tie_cfg:
	dev->cfg_pending = dev->cfg;
	rtnl_unlock();
out_dev:
	ethnl_parse_header_dev_put(&req_info);
+3 −5
Original line number Diff line number Diff line
@@ -294,13 +294,11 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
		return -EINVAL;
	}

	dev->cfg_pending->hds_config = kernel_ringparam.tcp_data_split;
	dev->cfg_pending->hds_thresh = kernel_ringparam.hds_thresh;

	ret = dev->ethtool_ops->set_ringparam(dev, &ringparam,
					      &kernel_ringparam, info->extack);
	if (!ret) {
		dev->cfg->hds_config = kernel_ringparam.tcp_data_split;
		dev->cfg->hds_thresh = kernel_ringparam.hds_thresh;
	}

	return ret < 0 ? ret : 1;
}