* [PATCH] net: fix the flow limitation computation
@ 2014-12-05 9:48 roy.qing.li
2014-12-05 14:49 ` Eric Dumazet
2014-12-05 17:52 ` Willem de Bruijn
0 siblings, 2 replies; 3+ messages in thread
From: roy.qing.li @ 2014-12-05 9:48 UTC (permalink / raw)
To: netdev
From: Li RongQing <roy.qing.li@gmail.com>
Once RPS is enabled, the skb maybe enqueue to different CPU, so the
flow limitation computation should use the enqueued CPU, not the local
CPU
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
---
net/core/dev.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 945bbd0..e70507d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3250,7 +3250,7 @@ static int rps_ipi_queued(struct softnet_data *sd)
int netdev_flow_limit_table_len __read_mostly = (1 << 12);
#endif
-static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
+static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen, int cpu)
{
#ifdef CONFIG_NET_FLOW_LIMIT
struct sd_flow_limit *fl;
@@ -3260,7 +3260,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
if (qlen < (netdev_max_backlog >> 1))
return false;
- sd = this_cpu_ptr(&softnet_data);
+ sd = &per_cpu(softnet_data, cpu);
rcu_read_lock();
fl = rcu_dereference(sd->flow_limit);
@@ -3303,7 +3303,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
rps_lock(sd);
qlen = skb_queue_len(&sd->input_pkt_queue);
- if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen)) {
+ if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen, cpu)) {
if (skb_queue_len(&sd->input_pkt_queue)) {
enqueue:
__skb_queue_tail(&sd->input_pkt_queue, skb);
--
2.1.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] net: fix the flow limitation computation
2014-12-05 9:48 [PATCH] net: fix the flow limitation computation roy.qing.li
@ 2014-12-05 14:49 ` Eric Dumazet
2014-12-05 17:52 ` Willem de Bruijn
1 sibling, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2014-12-05 14:49 UTC (permalink / raw)
To: roy.qing.li, Willem de Bruijn; +Cc: netdev
On Fri, 2014-12-05 at 17:48 +0800, roy.qing.li@gmail.com wrote:
> From: Li RongQing <roy.qing.li@gmail.com>
>
> Once RPS is enabled, the skb maybe enqueue to different CPU, so the
> flow limitation computation should use the enqueued CPU, not the local
> CPU
>
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
> ---
CC Willem de Bruijn <willemb@google.com>, author of this mechanism, for
comments.
> net/core/dev.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 945bbd0..e70507d 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3250,7 +3250,7 @@ static int rps_ipi_queued(struct softnet_data *sd)
> int netdev_flow_limit_table_len __read_mostly = (1 << 12);
> #endif
>
> -static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
> +static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen, int cpu)
> {
> #ifdef CONFIG_NET_FLOW_LIMIT
> struct sd_flow_limit *fl;
> @@ -3260,7 +3260,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
> if (qlen < (netdev_max_backlog >> 1))
> return false;
>
> - sd = this_cpu_ptr(&softnet_data);
> + sd = &per_cpu(softnet_data, cpu);
What about passing sd instead of cpu, so that we do not have to compute
this again ?
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] net: fix the flow limitation computation
2014-12-05 9:48 [PATCH] net: fix the flow limitation computation roy.qing.li
2014-12-05 14:49 ` Eric Dumazet
@ 2014-12-05 17:52 ` Willem de Bruijn
1 sibling, 0 replies; 3+ messages in thread
From: Willem de Bruijn @ 2014-12-05 17:52 UTC (permalink / raw)
To: roy.qing.li; +Cc: Network Development
On Fri, Dec 5, 2014 at 4:48 AM, <roy.qing.li@gmail.com> wrote:
> From: Li RongQing <roy.qing.li@gmail.com>
>
> Once RPS is enabled, the skb maybe enqueue to different CPU, so the
> flow limitation computation should use the enqueued CPU, not the local
> CPU
No, the decision to do accounting on the initial cpu was deliberate,
to avoids cache line contention with other cpus.
The goal is to detect under stress a single four-tuple that is
responsible for the majority of traffic, based on the assumption
that traffic is spread across many flows under normal conditions.
Accounting on the destination rps cpus is the more obviously
correct solution. Accounting on the source cpu is generally
fine, too, since it still only blocks a flow if that flow sends
> 50% of all packets from that cpu.
The only false positive occurs if multiple cpus have flows that
are large in proportion to their own packet rate, but only a subset
of these cpus actually generate a lot of traffic. Then, the
proportionally large flows from the cpus that generate little
traffic are incorrectly throttled. Throttling is still proportional
to aggregate packet rate, so should be low.
>
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
> ---
> net/core/dev.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 945bbd0..e70507d 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3250,7 +3250,7 @@ static int rps_ipi_queued(struct softnet_data *sd)
> int netdev_flow_limit_table_len __read_mostly = (1 << 12);
> #endif
>
> -static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
> +static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen, int cpu)
> {
> #ifdef CONFIG_NET_FLOW_LIMIT
> struct sd_flow_limit *fl;
> @@ -3260,7 +3260,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
> if (qlen < (netdev_max_backlog >> 1))
> return false;
>
> - sd = this_cpu_ptr(&softnet_data);
> + sd = &per_cpu(softnet_data, cpu);
>
> rcu_read_lock();
> fl = rcu_dereference(sd->flow_limit);
> @@ -3303,7 +3303,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
>
> rps_lock(sd);
> qlen = skb_queue_len(&sd->input_pkt_queue);
> - if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen)) {
> + if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen, cpu)) {
> if (skb_queue_len(&sd->input_pkt_queue)) {
> enqueue:
> __skb_queue_tail(&sd->input_pkt_queue, skb);
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-12-05 17:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-05 9:48 [PATCH] net: fix the flow limitation computation roy.qing.li
2014-12-05 14:49 ` Eric Dumazet
2014-12-05 17:52 ` Willem de Bruijn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox