RPS: Ensure that an expired hardware filter can be re-added later
authorBen Hutchings <bhutchings@solarflare.com>
Mon, 3 Oct 2011 04:42:46 +0000 (04:42 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Oct 2011 16:14:45 +0000 (12:14 -0400)
Amir Vadai wrote:
> When a stream is paused, and its rule is expired while it is paused,
> no new rule will be configured to the HW when traffic resume.
[...]
> - When stream was resumed, traffic was steered again by RSS, and
> because current-cpu was equal to desired-cpu,  ndo_rx_flow_steer
> wasn't called and no rule was configured to the HW.

Fix this by setting the flow's current CPU only in the table for the
newly selected RX queue.

Reported-and-tested-by: Amir Vadai <amirv@dev.mellanox.co.il>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/dev.c

index 7f4486e..70ecb86 100644 (file)
@@ -2670,10 +2670,7 @@ static struct rps_dev_flow *
 set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
            struct rps_dev_flow *rflow, u16 next_cpu)
 {
-       u16 tcpu;
-
-       tcpu = rflow->cpu = next_cpu;
-       if (tcpu != RPS_NO_CPU) {
+       if (next_cpu != RPS_NO_CPU) {
 #ifdef CONFIG_RFS_ACCEL
                struct netdev_rx_queue *rxqueue;
                struct rps_dev_flow_table *flow_table;
@@ -2701,16 +2698,16 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
                        goto out;
                old_rflow = rflow;
                rflow = &flow_table->flows[flow_id];
-               rflow->cpu = next_cpu;
                rflow->filter = rc;
                if (old_rflow->filter == rflow->filter)
                        old_rflow->filter = RPS_NO_FILTER;
        out:
 #endif
                rflow->last_qtail =
-                       per_cpu(softnet_data, tcpu).input_queue_head;
+                       per_cpu(softnet_data, next_cpu).input_queue_head;
        }
 
+       rflow->cpu = next_cpu;
        return rflow;
 }