pkt_sched: fq: fix non TCP flows pacing
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>
This commit is contained in:
Родитель
2b1f18a4d6
Коммит
7eec4174ff
|
@ -2319,6 +2319,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
||||||
sk->sk_ll_usec = sysctl_net_busy_read;
|
sk->sk_ll_usec = sysctl_net_busy_read;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
sk->sk_pacing_rate = ~0U;
|
||||||
/*
|
/*
|
||||||
* Before updating sk_refcnt, we must commit prior changes to memory
|
* Before updating sk_refcnt, we must commit prior changes to memory
|
||||||
* (Documentation/RCU/rculist_nulls.txt for details)
|
* (Documentation/RCU/rculist_nulls.txt for details)
|
||||||
|
|
|
@ -472,20 +472,16 @@ begin:
|
||||||
if (f->credit > 0 || !q->rate_enable)
|
if (f->credit > 0 || !q->rate_enable)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) {
|
rate = q->flow_max_rate;
|
||||||
rate = skb->sk->sk_pacing_rate ?: q->flow_default_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);
|
if (rate != ~0U) {
|
||||||
} else {
|
|
||||||
rate = q->flow_max_rate;
|
|
||||||
if (rate == ~0U)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (rate) {
|
|
||||||
u32 plen = max(qdisc_pkt_len(skb), q->quantum);
|
u32 plen = max(qdisc_pkt_len(skb), q->quantum);
|
||||||
u64 len = (u64)plen * NSEC_PER_SEC;
|
u64 len = (u64)plen * NSEC_PER_SEC;
|
||||||
|
|
||||||
do_div(len, rate);
|
if (likely(rate))
|
||||||
|
do_div(len, rate);
|
||||||
/* Since socket rate can change later,
|
/* Since socket rate can change later,
|
||||||
* clamp the delay to 125 ms.
|
* clamp the delay to 125 ms.
|
||||||
* TODO: maybe segment the too big skb, as in commit
|
* TODO: maybe segment the too big skb, as in commit
|
||||||
|
@ -735,12 +731,14 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
|
||||||
if (opts == NULL)
|
if (opts == NULL)
|
||||||
goto nla_put_failure;
|
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) ||
|
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_FLOW_PLIMIT, q->flow_plimit) ||
|
||||||
nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
|
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_INITIAL_QUANTUM, q->initial_quantum) ||
|
||||||
nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
|
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_FLOW_MAX_RATE, q->flow_max_rate) ||
|
||||||
nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
|
nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче