aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netdevsim/ethtool.c
diff options
context:
space:
mode:
authorBreno Leitao <[email protected]>2025-07-11 17:06:59 +0000
committerJakub Kicinski <[email protected]>2025-07-15 00:36:50 +0000
commitff2ac4df58adb6d7721bb0ce6069e1bd0e613126 (patch)
tree7b16726c806611ab3afa1213638e39ed885831af /drivers/net/netdevsim/ethtool.c
parentselftests: net: add test for variable PMTU in broadcast routes (diff)
downloadkernel-ff2ac4df58adb6d7721bb0ce6069e1bd0e613126.tar.gz
kernel-ff2ac4df58adb6d7721bb0ce6069e1bd0e613126.zip
netdevsim: implement peer queue flow control
Add flow control mechanism between paired netdevsim devices to stop the TX queue during high traffic scenarios. When a receive queue becomes congested (approaching NSIM_RING_SIZE limit), the corresponding transmit queue on the peer device is stopped using netif_subqueue_try_stop(). Once the receive queue has sufficient capacity again, the peer's transmit queue is resumed with netif_tx_wake_queue(). Key changes: * Add nsim_stop_peer_tx_queue() to pause peer TX when RX queue is full * Add nsim_start_peer_tx_queue() to resume peer TX when RX queue drains * Implement queue mapping validation to ensure TX/RX queue count match * Wake all queues during device unlinking to prevent stuck queues * Use RCU protection when accessing peer device references * wake the queues when changing the queue numbers * Remove IFF_NO_QUEUE given it will enqueue packets now The flow control only activates when devices have matching TX/RX queue counts to ensure proper queue mapping. Suggested-by: Jakub Kicinski <[email protected]> Signed-off-by: Breno Leitao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'drivers/net/netdevsim/ethtool.c')
-rw-r--r--drivers/net/netdevsim/ethtool.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 4d191a3293c7..f631d90c428a 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -101,6 +101,22 @@ nsim_get_channels(struct net_device *dev, struct ethtool_channels *ch)
ch->combined_count = ns->ethtool.channels;
}
+static void
+nsim_wake_queues(struct net_device *dev)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ struct netdevsim *peer;
+
+ synchronize_net();
+ netif_tx_wake_all_queues(dev);
+
+ rcu_read_lock();
+ peer = rcu_dereference(ns->peer);
+ if (peer)
+ netif_tx_wake_all_queues(peer->netdev);
+ rcu_read_unlock();
+}
+
static int
nsim_set_channels(struct net_device *dev, struct ethtool_channels *ch)
{
@@ -113,6 +129,11 @@ nsim_set_channels(struct net_device *dev, struct ethtool_channels *ch)
return err;
ns->ethtool.channels = ch->combined_count;
+
+ /* Only wake up queues if devices are linked */
+ if (rcu_access_pointer(ns->peer))
+ nsim_wake_queues(dev);
+
return 0;
}