[RFC,03/11] arfs: Create set_arfs_queue

Message ID 20200624171749.11927-4-tom@herbertland.com
State New
Headers show
Series
  • [RFC,01/11] cgroup: Export cgroup_{procs,threads}_start and cgroup_procs_next
Related show

Commit Message

Tom Herbert June 24, 2020, 5:17 p.m.
Abstract out the code for steering a flow to an aRFS queue (via
ndo_rx_flow_steer) into its own function. This allows the function to
be called in other use cases.
---
 net/core/dev.c | 67 +++++++++++++++++++++++++++++---------------------
 1 file changed, 39 insertions(+), 28 deletions(-)

Patch

diff --git a/net/core/dev.c b/net/core/dev.c
index 6bc2388141f6..9f7a3e78e23a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4250,42 +4250,53 @@  EXPORT_SYMBOL(rps_needed);
 struct static_key_false rfs_needed __read_mostly;
 EXPORT_SYMBOL(rfs_needed);
 
+#ifdef CONFIG_RFS_ACCEL
+static void set_arfs_queue(struct net_device *dev, struct sk_buff *skb,
+			   struct rps_dev_flow *rflow, u16 rxq_index)
+{
+	struct rps_dev_flow_table *flow_table;
+	struct netdev_rx_queue *rxqueue;
+	struct rps_dev_flow *old_rflow;
+	u32 flow_id;
+	int rc;
+
+	rxqueue = dev->_rx + rxq_index;
+
+	flow_table = rcu_dereference(rxqueue->rps_flow_table);
+	if (!flow_table)
+		return;
+
+	flow_id = skb_get_hash(skb) & flow_table->mask;
+	rc = dev->netdev_ops->ndo_rx_flow_steer(dev, skb,
+						rxq_index, flow_id);
+	if (rc < 0)
+		return;
+
+	old_rflow = rflow;
+	rflow = &flow_table->flows[flow_id];
+	rflow->filter = rc;
+	if (old_rflow->filter == rflow->filter)
+		old_rflow->filter = RPS_NO_FILTER;
+}
+#endif
+
 static struct rps_dev_flow *
 set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 	    struct rps_dev_flow *rflow, u16 next_cpu)
 {
 	if (next_cpu < nr_cpu_ids) {
 #ifdef CONFIG_RFS_ACCEL
-		struct netdev_rx_queue *rxqueue;
-		struct rps_dev_flow_table *flow_table;
-		struct rps_dev_flow *old_rflow;
-		u32 flow_id;
-		u16 rxq_index;
-		int rc;
 
 		/* Should we steer this flow to a different hardware queue? */
-		if (!skb_rx_queue_recorded(skb) || !dev->rx_cpu_rmap ||
-		    !(dev->features & NETIF_F_NTUPLE))
-			goto out;
-		rxq_index = cpu_rmap_lookup_index(dev->rx_cpu_rmap, next_cpu);
-		if (rxq_index == skb_get_rx_queue(skb))
-			goto out;
-
-		rxqueue = dev->_rx + rxq_index;
-		flow_table = rcu_dereference(rxqueue->rps_flow_table);
-		if (!flow_table)
-			goto out;
-		flow_id = skb_get_hash(skb) & flow_table->mask;
-		rc = dev->netdev_ops->ndo_rx_flow_steer(dev, skb,
-							rxq_index, flow_id);
-		if (rc < 0)
-			goto out;
-		old_rflow = rflow;
-		rflow = &flow_table->flows[flow_id];
-		rflow->filter = rc;
-		if (old_rflow->filter == rflow->filter)
-			old_rflow->filter = RPS_NO_FILTER;
-	out:
+		if (skb_rx_queue_recorded(skb) && dev->rx_cpu_rmap &&
+		    (dev->features & NETIF_F_NTUPLE)) {
+			u16 rxq_index;
+
+			rxq_index = cpu_rmap_lookup_index(dev->rx_cpu_rmap,
+							  next_cpu);
+			if (rxq_index != skb_get_rx_queue(skb))
+				set_arfs_queue(dev, skb, rflow, rxq_index);
+		}
 #endif
 		rflow->last_qtail =
 			per_cpu(softnet_data, next_cpu).input_queue_head;