@@ -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;