Commit ff7d4deb authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski
Browse files

net-shapers: implement shaper cleanup on queue deletion



hook into netif_set_real_num_tx_queues() to cleanup any shaper
configured on top of the to-be-destroyed TX queues.

Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Link: https://patch.msgid.link/6da4ee03cae2b2a757d7b59e88baf09cc94c5ef1.1728460186.git.pabeni@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bf230c49
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2949,6 +2949,8 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
		if (dev->num_tc)
			netif_setup_tc(dev, txq);

		net_shaper_set_real_num_tx_queues(dev, txq);

		dev_qdisc_change_real_num_tx(dev, txq);

		dev->real_num_tx_queues = txq;
+4 −0
Original line number Diff line number Diff line
@@ -37,8 +37,12 @@ void dev_addr_check(struct net_device *dev);

#if IS_ENABLED(CONFIG_NET_SHAPER)
void net_shaper_flush_netdev(struct net_device *dev);
void net_shaper_set_real_num_tx_queues(struct net_device *dev,
				       unsigned int txq);
#else
static inline void net_shaper_flush_netdev(struct net_device *dev) {}
static inline void net_shaper_set_real_num_tx_queues(struct net_device *dev,
						     unsigned int txq) {}
#endif

/* sysctls not referred to from outside net/core/ */
+48 −0
Original line number Diff line number Diff line
@@ -1157,6 +1157,54 @@ void net_shaper_flush_netdev(struct net_device *dev)
	net_shaper_flush(&binding);
}

void net_shaper_set_real_num_tx_queues(struct net_device *dev,
				       unsigned int txq)
{
	struct net_shaper_hierarchy *hierarchy;
	struct net_shaper_binding binding;
	int i;

	binding.type = NET_SHAPER_BINDING_TYPE_NETDEV;
	binding.netdev = dev;
	hierarchy = net_shaper_hierarchy(&binding);
	if (!hierarchy)
		return;

	/* Only drivers implementing shapers support ensure
	 * the lock is acquired in advance.
	 */
	lockdep_assert_held(&dev->lock);

	/* Take action only when decreasing the tx queue number. */
	for (i = txq; i < dev->real_num_tx_queues; ++i) {
		struct net_shaper_handle handle, parent_handle;
		struct net_shaper *shaper;
		u32 index;

		handle.scope = NET_SHAPER_SCOPE_QUEUE;
		handle.id = i;
		shaper = net_shaper_lookup(&binding, &handle);
		if (!shaper)
			continue;

		/* Don't touch the H/W for the queue shaper, the drivers already
		 * deleted the queue and related resources.
		 */
		parent_handle = shaper->parent;
		index = net_shaper_handle_to_index(&handle);
		xa_erase(&hierarchy->shapers, index);
		kfree_rcu(shaper, rcu);

		/* The recursion on parent does the full job. */
		if (parent_handle.scope != NET_SHAPER_SCOPE_NODE)
			continue;

		shaper = net_shaper_lookup(&binding, &parent_handle);
		if (shaper && !--shaper->leaves)
			__net_shaper_delete(&binding, shaper, NULL);
	}
}

static int __init shaper_init(void)
{
	return genl_register_family(&net_shaper_nl_family);