Skip to content

Commit

Permalink
pkt_sched: fq: fix non TCP flows pacing
Browse files Browse the repository at this point in the history
Steinar reported FQ pacing was not working for UDP flows.

It looks like the initial sk->sk_pacing_rate value of 0 was
a wrong choice. We should init it to ~0U (unlimited)

Then, TCA_FQ_FLOW_DEFAULT_RATE should be removed because it makes
no real sense. The default rate is really unlimited, and we
need to avoid a zero divide.

Reported-by: Steinar H. Gunderson <sesse@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Oct 9, 2013
1 parent 2b1f18a commit 7eec417
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 11 deletions.
1 change: 1 addition & 0 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_ll_usec = sysctl_net_busy_read;
#endif

sk->sk_pacing_rate = ~0U;
/*
* Before updating sk_refcnt, we must commit prior changes to memory
* (Documentation/RCU/rculist_nulls.txt for details)
Expand Down
20 changes: 9 additions & 11 deletions net/sched/sch_fq.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,20 +472,16 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch)
if (f->credit > 0 || !q->rate_enable)
goto out;

if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) {
rate = skb->sk->sk_pacing_rate ?: q->flow_default_rate;
rate = q->flow_max_rate;
if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT)
rate = min(skb->sk->sk_pacing_rate, rate);

rate = min(rate, q->flow_max_rate);
} else {
rate = q->flow_max_rate;
if (rate == ~0U)
goto out;
}
if (rate) {
if (rate != ~0U) {
u32 plen = max(qdisc_pkt_len(skb), q->quantum);
u64 len = (u64)plen * NSEC_PER_SEC;

do_div(len, rate);
if (likely(rate))
do_div(len, rate);
/* Since socket rate can change later,
* clamp the delay to 125 ms.
* TODO: maybe segment the too big skb, as in commit
Expand Down Expand Up @@ -735,12 +731,14 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
if (opts == NULL)
goto nla_put_failure;

/* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore,
* do not bother giving its value
*/
if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) ||
nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) ||
nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) ||
nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
nla_put_u32(skb, TCA_FQ_FLOW_DEFAULT_RATE, q->flow_default_rate) ||
nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) ||
nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
goto nla_put_failure;
Expand Down

0 comments on commit 7eec417

Please sign in to comment.