mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
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: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Link: https://patch.msgid.link/6da4ee03cae2b2a757d7b59e88baf09cc94c5ef1.1728460186.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
bf230c497d
commit
ff7d4deb1f
@ -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;
|
||||
|
@ -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/ */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user