diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-10-03 00:42:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-03 12:14:45 -0400 |
commit | 09994d1b09bd9b0046a4708fa50d2106610a4058 (patch) | |
tree | 1bd59c2e19b01e30e5666dd483df6d6254b82995 /net | |
parent | 76231e0297db30f1f0e947a02b42495e7d535d56 (diff) |
RPS: Ensure that an expired hardware filter can be re-added later
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 7f4486e127e9..70ecb86439ca 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2670,10 +2670,7 @@ static struct rps_dev_flow * | |||
2670 | set_rps_cpu(struct net_device *dev, struct sk_buff *skb, | 2670 | set_rps_cpu(struct net_device *dev, struct sk_buff *skb, |
2671 | struct rps_dev_flow *rflow, u16 next_cpu) | 2671 | struct rps_dev_flow *rflow, u16 next_cpu) |
2672 | { | 2672 | { |
2673 | u16 tcpu; | 2673 | if (next_cpu != RPS_NO_CPU) { |
2674 | |||
2675 | tcpu = rflow->cpu = next_cpu; | ||
2676 | if (tcpu != RPS_NO_CPU) { | ||
2677 | #ifdef CONFIG_RFS_ACCEL | 2674 | #ifdef CONFIG_RFS_ACCEL |
2678 | struct netdev_rx_queue *rxqueue; | 2675 | struct netdev_rx_queue *rxqueue; |
2679 | struct rps_dev_flow_table *flow_table; | 2676 | struct rps_dev_flow_table *flow_table; |
@@ -2701,16 +2698,16 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2701 | goto out; | 2698 | goto out; |
2702 | old_rflow = rflow; | 2699 | old_rflow = rflow; |
2703 | rflow = &flow_table->flows[flow_id]; | 2700 | rflow = &flow_table->flows[flow_id]; |
2704 | rflow->cpu = next_cpu; | ||
2705 | rflow->filter = rc; | 2701 | rflow->filter = rc; |
2706 | if (old_rflow->filter == rflow->filter) | 2702 | if (old_rflow->filter == rflow->filter) |
2707 | old_rflow->filter = RPS_NO_FILTER; | 2703 | old_rflow->filter = RPS_NO_FILTER; |
2708 | out: | 2704 | out: |
2709 | #endif | 2705 | #endif |
2710 | rflow->last_qtail = | 2706 | rflow->last_qtail = |
2711 | per_cpu(softnet_data, tcpu).input_queue_head; | 2707 | per_cpu(softnet_data, next_cpu).input_queue_head; |
2712 | } | 2708 | } |
2713 | 2709 | ||
2710 | rflow->cpu = next_cpu; | ||
2714 | return rflow; | 2711 | return rflow; |
2715 | } | 2712 | } |
2716 | 2713 | ||