From: Eric Dumazet edumazet@google.com
mainline inclusion from mainline-v5.3.0 commit 08e14fe429a07475ee9f29a283945d602e4a6d92 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4AFRJ?from=project-issue CVE: NA ------------------------------------------------------------
When EDT conversion happened, fq lost the ability to enfore a maxrate for all flows. It kept it for non EDT flows.
This commit restores the functionality.
Tested:
tc qd replace dev eth0 root fq maxrate 500Mbit netperf -P0 -H host -- -O THROUGHPUT 489.75
Fixes: ab408b6dc744 ("tcp: switch tcp and sch_fq to new earliest departure time model") Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Jiazhenyuan jiazhenyuan@uniontech.com --- net/sched/sch_fq.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 41cb947917fc..64d7f11b0240 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -516,22 +516,29 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch) goto begin; } prefetch(&skb->end); - f->credit -= qdisc_pkt_len(skb); + plen = qdisc_pkt_len(skb); + f->credit -= plen;
- if (ktime_to_ns(skb->tstamp) || !q->rate_enable) + if (!q->rate_enable) goto out;
rate = q->flow_max_rate; - if (skb->sk) - rate = min(skb->sk->sk_pacing_rate, rate);
- if (rate <= q->low_rate_threshold) { - f->credit = 0; - plen = qdisc_pkt_len(skb); - } else { - plen = max(qdisc_pkt_len(skb), q->quantum); - if (f->credit > 0) - goto out; + /* If EDT time was provided for this skb, we need to + * update f->time_next_packet only if this qdisc enforces + * a flow max rate. + */ + if (!skb->tstamp) { + if (skb->sk) + rate = min(skb->sk->sk_pacing_rate, rate); + + if (rate <= q->low_rate_threshold) { + f->credit = 0; + } else { + plen = max(plen, q->quantum); + if (f->credit > 0) + goto out; + } } if (rate != ~0U) { u64 len = (u64)plen * NSEC_PER_SEC;