From: Amir Vadai <hidden> Date: 2011-09-19 06:05:09
(Resending in plain text)
Tom Hi,
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.
Scenario:
1. Start iperf.
2. Pause it using Ctrl-Z
3. Start another iperf (to make sure first stream rule is expired)
4. Stop the second stream.
5. Resume first stream. Traffic is not steered to the right rx-queue.
From looking at the code:
- When first stream started, RSS steered traffic to rx-queue 'x'.
Because iperf server was running on a different CPU, a new rule was
added and current-cpu was set to desired-cpu.
- After paused, rule was expired and removed from HW by net driver.
But current-cpu wasn't cleared and still is equal to desired-cpu.
- 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.
Why isn't current-cpu cleared when expiring a rule?
- Amir
From: Tom Herbert <hidden> Date: 2011-09-19 15:13:37
Ben: Once a accel RFS flow expires (because flow is idle?), how
should it get re-instantiated if thread's CPU doesn't change?
Tom
On Sun, Sep 18, 2011 at 11:05 PM, Amir Vadai [off-list ref] wrote:
(Resending in plain text)
Tom Hi,
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.
Scenario:
1. Start iperf.
2. Pause it using Ctrl-Z
3. Start another iperf (to make sure first stream rule is expired)
4. Stop the second stream.
5. Resume first stream. Traffic is not steered to the right rx-queue.
From looking at the code:
- When first stream started, RSS steered traffic to rx-queue 'x'.
Because iperf server was running on a different CPU, a new rule was
added and current-cpu was set to desired-cpu.
- After paused, rule was expired and removed from HW by net driver.
But current-cpu wasn't cleared and still is equal to desired-cpu.
- 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.
Why isn't current-cpu cleared when expiring a rule?
- Amir
From: Ben Hutchings <hidden> Date: 2011-09-19 15:52:56
On Mon, 2011-09-19 at 08:13 -0700, Tom Herbert wrote:
Ben: Once a accel RFS flow expires (because flow is idle?), how
should it get re-instantiated if thread's CPU doesn't change?
Good question.
Tom
On Sun, Sep 18, 2011 at 11:05 PM, Amir Vadai [off-list ref] wrote:
quoted
(Resending in plain text)
Tom Hi,
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.
Scenario:
1. Start iperf.
2. Pause it using Ctrl-Z
3. Start another iperf (to make sure first stream rule is expired)
4. Stop the second stream.
5. Resume first stream. Traffic is not steered to the right rx-queue.
From looking at the code:
- When first stream started, RSS steered traffic to rx-queue 'x'.
Because iperf server was running on a different CPU, a new rule was
added and current-cpu was set to desired-cpu.
- After paused, rule was expired and removed from HW by net driver.
But current-cpu wasn't cleared and still is equal to desired-cpu.
- 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.
Why isn't current-cpu cleared when expiring a rule?
Because I wrongly assumed that rules could be independently expired by
the driver and the RPS/RFS core code.
Try this (I haven't tested it myself yet):
From: Ben Hutchings <redacted>
Date: Mon, 19 Sep 2011 16:44:13 +0100
Subject: [PATCH net-next] RPS: When a hardware filter is expired, ensure it
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.
Why isn't current-cpu cleared when expiring a rule?
When rps_may_expire_flow() matches a filter to a flow that is found to
be idle, unset the current CPU for that flow.
Reported-by: Amir Vadai <redacted>
---
net/core/dev.c | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
@@ -2817,11 +2817,22 @@ bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index,if(flow_table&&flow_id<=flow_table->mask){rflow=&flow_table->flows[flow_id];cpu=ACCESS_ONCE(rflow->cpu);-if(rflow->filter==filter_id&&cpu!=RPS_NO_CPU&&-((int)(per_cpu(softnet_data,cpu).input_queue_head--rflow->last_qtail)<-(int)(10*flow_table->mask)))-expire=false;+if(rflow->filter==filter_id&&cpu!=RPS_NO_CPU){+if((int)(per_cpu(softnet_data,cpu).input_queue_head-+rflow->last_qtail)<+(int)(10*flow_table->mask)){+expire=false;+}else{+/* If this flow (or a flow with the+*samehashvalue)becomesactive+*ontheCPUasbefore,wewantto+*restorethehardwarefilter.Unset+*thecurrentCPUtoensurethat+*set_rps_cpu()willbecalledthen.+*/+rflow->cpu=RPS_NO_CPU;+}+}}rcu_read_unlock();returnexpire;
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
From: Amir Vadai <hidden> Date: 2011-09-20 06:53:16
This will unset the current CPU of the rflow that belongs to the desired CPU.
The problem is when the stream resumes and it goes to the wrong RXQ - in our HW, it will be according to RSS, as long as there is no specific flow steering rule for the stream.
We need to unset the current CPU of the rflow of the actual RXQ that the packet arrived at:
@@ -2685,6 +2685,12 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,rflow=&flow_table->flows[flow_id];rflow->cpu=next_cpu;rflow->filter=rc;+/* If this flow (or a flow with the same hash value) becomes+*activeontheCPUasbefore,wewanttorestorethe+*hardwarefilter.UnsetthecurrentCPUtoensurethat+*set_rps_cpu()willbecalledthen.+*/+old_rflow->cpu=RPS_NO_CPU;if(old_rflow->filter==rflow->filter)old_rflow->filter=RPS_NO_FILTER;out:
Or even better, not set it in the first place - but I'm not sure I undersdtand the implications on RPS:
On Mon, 2011-09-19 at 08:13 -0700, Tom Herbert wrote:
quoted
Ben: Once a accel RFS flow expires (because flow is idle?), how
should it get re-instantiated if thread's CPU doesn't change?
Good question.
quoted
Tom
On Sun, Sep 18, 2011 at 11:05 PM, Amir Vadai[off-list ref] wrote:
quoted
(Resending in plain text)
Tom Hi,
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.
Scenario:
1. Start iperf.
2. Pause it using Ctrl-Z
3. Start another iperf (to make sure first stream rule is expired)
4. Stop the second stream.
5. Resume first stream. Traffic is not steered to the right rx-queue.
From looking at the code:
- When first stream started, RSS steered traffic to rx-queue 'x'.
Because iperf server was running on a different CPU, a new rule was
added and current-cpu was set to desired-cpu.
- After paused, rule was expired and removed from HW by net driver.
But current-cpu wasn't cleared and still is equal to desired-cpu.
- 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.
Why isn't current-cpu cleared when expiring a rule?
Because I wrongly assumed that rules could be independently expired by
the driver and the RPS/RFS core code.
Try this (I haven't tested it myself yet):
From: Ben Hutchings<redacted>
Date: Mon, 19 Sep 2011 16:44:13 +0100
Subject: [PATCH net-next] RPS: When a hardware filter is expired, ensure it
can be re-added later
Amir Vadai wrote:
quoted
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.
[...]
quoted
- 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.
Why isn't current-cpu cleared when expiring a rule?
When rps_may_expire_flow() matches a filter to a flow that is found to
be idle, unset the current CPU for that flow.
Reported-by: Amir Vadai<redacted>
---
net/core/dev.c | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
@@ -2817,11 +2817,22 @@ bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index,if(flow_table&&flow_id<=flow_table->mask){rflow=&flow_table->flows[flow_id];cpu=ACCESS_ONCE(rflow->cpu);-if(rflow->filter==filter_id&&cpu!=RPS_NO_CPU&&-((int)(per_cpu(softnet_data,cpu).input_queue_head--rflow->last_qtail)<-(int)(10*flow_table->mask)))-expire=false;+if(rflow->filter==filter_id&&cpu!=RPS_NO_CPU){+if((int)(per_cpu(softnet_data,cpu).input_queue_head-+rflow->last_qtail)<+(int)(10*flow_table->mask)){+expire=false;+}else{+/* If this flow (or a flow with the+*samehashvalue)becomesactive+*ontheCPUasbefore,wewantto+*restorethehardwarefilter.Unset+*thecurrentCPUtoensurethat+*set_rps_cpu()willbecalledthen.+*/+rflow->cpu=RPS_NO_CPU;+}+}}rcu_read_unlock();returnexpire;
From: Ben Hutchings <hidden> Date: 2011-09-21 15:09:07
On Tue, 2011-09-20 at 09:53 +0300, Amir Vadai wrote:
This will unset the current CPU of the rflow that belongs to the desired
CPU.
The problem is when the stream resumes and it goes to the wrong RXQ - in
our HW, it will be according to RSS, as long as there is no specific
flow steering rule for the stream.
Sorry, yes. Told you I didn't test my patch!
We need to unset the current CPU of the rflow of the actual RXQ that the
packet arrived at:
[...]
quoted hunk
Or even better, not set it in the first place - but I'm not sure I
undersdtand the implications on RPS:
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
From: Amir Vadai <hidden> Date: 2011-09-22 06:11:52
Looks good.
and now the code is much clearer
- Amir
On 09/21/2011 06:09 PM, Ben Hutchings wrote:
quoted hunk
On Tue, 2011-09-20 at 09:53 +0300, Amir Vadai wrote:
quoted
This will unset the current CPU of the rflow that belongs to the desired
CPU.
The problem is when the stream resumes and it goes to the wrong RXQ - in
our HW, it will be according to RSS, as long as there is no specific
flow steering rule for the stream.
Sorry, yes. Told you I didn't test my patch!
quoted
We need to unset the current CPU of the rflow of the actual RXQ that the
packet arrived at:
[...]
quoted
Or even better, not set it in the first place - but I'm not sure I
undersdtand the implications on RPS:
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.