[PATCH v2 3/4] net: ntb_netdev: Factor out multi-queue helpers
From: Koichiro Den
Date: Sat Feb 28 2026 - 09:58:42 EST
Implementing .set_channels will otherwise duplicate the same multi-queue
operations at multiple call sites. Factor out the following helpers:
- ntb_netdev_update_carrier(): carrier is switched on when at least
one QP link is up
- ntb_netdev_queue_rx_drain(): drain and free all queued RX packets
for one QP
- ntb_netdev_queue_rx_fill(): prefill RX ring for one QP
No functional change.
Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
drivers/net/ntb_netdev.c | 99 ++++++++++++++++++++++++----------------
1 file changed, 59 insertions(+), 40 deletions(-)
diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
index 19a3383d86f8..6aa59316569c 100644
--- a/drivers/net/ntb_netdev.c
+++ b/drivers/net/ntb_netdev.c
@@ -94,24 +94,12 @@ struct ntb_netdev {
#define NTB_TX_TIMEOUT_MS 1000
#define NTB_RXQ_SIZE 100
-static void ntb_netdev_event_handler(void *data, int link_is_up)
+static void ntb_netdev_update_carrier(struct ntb_netdev *dev)
{
- struct ntb_netdev_queue *q = data;
- struct ntb_netdev *dev = q->ntdev;
struct net_device *ndev = dev->ndev;
bool any_up = false;
unsigned int i;
- netdev_dbg(ndev, "Event %x, Link %x, qp %u\n", link_is_up,
- ntb_transport_link_query(q->qp), q->qid);
-
- if (netif_running(ndev)) {
- if (link_is_up)
- netif_wake_subqueue(ndev, q->qid);
- else
- netif_stop_subqueue(ndev, q->qid);
- }
-
for (i = 0; i < dev->num_queues; i++) {
if (ntb_transport_link_query(dev->queues[i].qp)) {
any_up = true;
@@ -125,6 +113,56 @@ static void ntb_netdev_event_handler(void *data, int link_is_up)
netif_carrier_off(ndev);
}
+static void ntb_netdev_queue_rx_drain(struct ntb_netdev_queue *queue)
+{
+ struct sk_buff *skb;
+ int len;
+
+ while ((skb = ntb_transport_rx_remove(queue->qp, &len)))
+ dev_kfree_skb(skb);
+}
+
+static int ntb_netdev_queue_rx_fill(struct net_device *ndev,
+ struct ntb_netdev_queue *queue)
+{
+ struct sk_buff *skb;
+ int rc, i;
+
+ for (i = 0; i < NTB_RXQ_SIZE; i++) {
+ skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
+ if (!skb)
+ return -ENOMEM;
+
+ rc = ntb_transport_rx_enqueue(queue->qp, skb, skb->data,
+ ndev->mtu + ETH_HLEN);
+ if (rc) {
+ dev_kfree_skb(skb);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static void ntb_netdev_event_handler(void *data, int link_is_up)
+{
+ struct ntb_netdev_queue *q = data;
+ struct ntb_netdev *dev = q->ntdev;
+ struct net_device *ndev = dev->ndev;
+
+ netdev_dbg(ndev, "Event %x, Link %x, qp %u\n", link_is_up,
+ ntb_transport_link_query(q->qp), q->qid);
+
+ if (netif_running(ndev)) {
+ if (link_is_up)
+ netif_wake_subqueue(ndev, q->qid);
+ else
+ netif_stop_subqueue(ndev, q->qid);
+ }
+
+ ntb_netdev_update_carrier(dev);
+}
+
static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
void *data, int len)
{
@@ -299,28 +337,16 @@ static int ntb_netdev_open(struct net_device *ndev)
{
struct ntb_netdev *dev = netdev_priv(ndev);
struct ntb_netdev_queue *queue;
- struct sk_buff *skb;
unsigned int q;
- int rc = 0, i, len;
+ int rc = 0;
/* Add some empty rx bufs for each queue */
for (q = 0; q < dev->num_queues; q++) {
queue = &dev->queues[q];
- for (i = 0; i < NTB_RXQ_SIZE; i++) {
- skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
- if (!skb) {
- rc = -ENOMEM;
- goto err;
- }
-
- rc = ntb_transport_rx_enqueue(queue->qp, skb, skb->data,
- ndev->mtu + ETH_HLEN);
- if (rc) {
- dev_kfree_skb(skb);
- goto err;
- }
- }
+ rc = ntb_netdev_queue_rx_fill(ndev, queue);
+ if (rc)
+ goto err;
timer_setup(&queue->tx_timer, ntb_netdev_tx_timer, 0);
}
@@ -336,9 +362,7 @@ static int ntb_netdev_open(struct net_device *ndev)
err:
for (q = 0; q < dev->num_queues; q++) {
queue = &dev->queues[q];
-
- while ((skb = ntb_transport_rx_remove(queue->qp, &len)))
- dev_kfree_skb(skb);
+ ntb_netdev_queue_rx_drain(queue);
}
return rc;
}
@@ -347,9 +371,7 @@ static int ntb_netdev_close(struct net_device *ndev)
{
struct ntb_netdev *dev = netdev_priv(ndev);
struct ntb_netdev_queue *queue;
- struct sk_buff *skb;
unsigned int q;
- int len;
netif_tx_stop_all_queues(ndev);
netif_carrier_off(ndev);
@@ -358,12 +380,10 @@ static int ntb_netdev_close(struct net_device *ndev)
queue = &dev->queues[q];
ntb_transport_link_down(queue->qp);
-
- while ((skb = ntb_transport_rx_remove(queue->qp, &len)))
- dev_kfree_skb(skb);
-
+ ntb_netdev_queue_rx_drain(queue);
timer_delete_sync(&queue->tx_timer);
}
+
return 0;
}
@@ -429,8 +449,7 @@ static int ntb_netdev_change_mtu(struct net_device *ndev, int new_mtu)
ntb_transport_link_down(queue->qp);
- while ((skb = ntb_transport_rx_remove(queue->qp, &len)))
- dev_kfree_skb(skb);
+ ntb_netdev_queue_rx_drain(queue);
}
netdev_err(ndev, "Error changing MTU, device inoperable\n");
--
2.51.0