[PATCH net-next] net: core: Call netif_get_rxqueue() in get_rps_cpu()

Yue Haibing posted 1 patch 1 month, 2 weeks ago
net/core/dev.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
[PATCH net-next] net: core: Call netif_get_rxqueue() in get_rps_cpu()
Posted by Yue Haibing 1 month, 2 weeks ago
Refactor netif_get_rxqueue() return NULL when rxq index checking failed
instead of falling back to first queue, then use it to avoid code
duplication.

Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
---
 net/core/dev.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index e7bc95cbd1fa..72aef872d03c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5104,6 +5104,8 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 	return rflow;
 }
 
+static struct netdev_rx_queue *netif_get_rxqueue(struct sk_buff *skb);
+
 /*
  * get_rps_cpu is called from netif_receive_skb and returns the target
  * CPU from the RPS map of the receiving queue for a given skb.
@@ -5112,25 +5114,16 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 		       struct rps_dev_flow **rflowp)
 {
-	struct netdev_rx_queue *rxqueue = dev->_rx;
+	struct netdev_rx_queue *rxqueue;
 	rps_tag_ptr global_tag_ptr, q_tag_ptr;
 	struct rps_map *map;
 	int cpu = -1;
 	u32 tcpu;
 	u32 hash;
 
-	if (skb_rx_queue_recorded(skb)) {
-		u16 index = skb_get_rx_queue(skb);
-
-		if (unlikely(index >= dev->real_num_rx_queues)) {
-			WARN_ONCE(dev->real_num_rx_queues > 1,
-				  "%s received packet on queue %u, but number "
-				  "of RX queues is %u\n",
-				  dev->name, index, dev->real_num_rx_queues);
-			goto done;
-		}
-		rxqueue += index;
-	}
+	rxqueue = netif_get_rxqueue(skb);
+	if (!rxqueue)
+		goto done;
 
 	/* Avoid computing hash if RFS/RPS is not active for this rxqueue */
 
@@ -5442,8 +5435,7 @@ static struct netdev_rx_queue *netif_get_rxqueue(struct sk_buff *skb)
 				  "%s received packet on queue %u, but number "
 				  "of RX queues is %u\n",
 				  dev->name, index, dev->real_num_rx_queues);
-
-			return rxqueue; /* Return first rxqueue */
+			return NULL;
 		}
 		rxqueue += index;
 	}
@@ -5473,6 +5465,8 @@ u32 bpf_prog_run_generic_xdp(struct sk_buff *skb, struct xdp_buff *xdp,
 	frame_sz += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
 	rxqueue = netif_get_rxqueue(skb);
+	if (!rxqueue)
+		rxqueue = skb->dev->_rx;
 	xdp_init_buff(xdp, frame_sz, &rxqueue->xdp_rxq);
 	xdp_prepare_buff(xdp, hard_start, skb_headroom(skb) - mac_len,
 			 skb_headlen(skb) + mac_len, true);
-- 
2.34.1
Re: [PATCH net-next] net: core: Call netif_get_rxqueue() in get_rps_cpu()
Posted by Eric Dumazet 1 month, 2 weeks ago
On Wed, Apr 29, 2026 at 5:15 AM Yue Haibing <yuehaibing@huawei.com> wrote:
>
> Refactor netif_get_rxqueue() return NULL when rxq index checking failed
> instead of falling back to first queue, then use it to avoid code
> duplication.
>
> Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
> ---
>  net/core/dev.c | 24 +++++++++---------------
>  1 file changed, 9 insertions(+), 15 deletions(-)
>

This code (get_rps_cpu()) is super hot for some of us.

Are you sure netif_get_rxqueue() is kept inline?

I do not think gcc is smart enough:

scripts/bloat-o-meter -t net/core/dev.o.before net/core/dev.o.after
add/remove: 1/0 grow/shrink: 2/2 up/down: 116/-132 (-16)
Function                                     old     new   delta
netif_get_rxqueue.isra                         -      84     +84
dev_getbyhwaddr_rcu                          133     149     +16
__netif_set_xps_queue                       2837    2853     +16
bpf_prog_run_generic_xdp                     899     846     -53
get_rps_cpu                                  835     756     -79
      // This is bad,
Total: Before=90848, After=90832, chg -0.02%