diff options
| author | Breno Leitao <[email protected]> | 2025-07-11 17:06:59 +0000 |
|---|---|---|
| committer | Jakub Kicinski <[email protected]> | 2025-07-15 00:36:50 +0000 |
| commit | ff2ac4df58adb6d7721bb0ce6069e1bd0e613126 (patch) | |
| tree | 7b16726c806611ab3afa1213638e39ed885831af /drivers/net/netdevsim/ethtool.c | |
| parent | selftests: net: add test for variable PMTU in broadcast routes (diff) | |
| download | kernel-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.c | 21 |
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; } |
