aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_fq.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_fq.c')
-rw-r--r--net/sched/sch_fq.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index fc6de56a331e..a2fef8b10b96 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -420,6 +420,7 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch)
420 struct fq_flow_head *head; 420 struct fq_flow_head *head;
421 struct sk_buff *skb; 421 struct sk_buff *skb;
422 struct fq_flow *f; 422 struct fq_flow *f;
423 u32 rate;
423 424
424 skb = fq_dequeue_head(sch, &q->internal); 425 skb = fq_dequeue_head(sch, &q->internal);
425 if (skb) 426 if (skb)
@@ -468,28 +469,34 @@ begin:
468 f->time_next_packet = now; 469 f->time_next_packet = now;
469 f->credit -= qdisc_pkt_len(skb); 470 f->credit -= qdisc_pkt_len(skb);
470 471
471 if (f->credit <= 0 && 472 if (f->credit > 0 || !q->rate_enable)
472 q->rate_enable && 473 goto out;
473 skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) {
474 u32 rate = skb->sk->sk_pacing_rate ?: q->flow_default_rate;
475 474
476 rate = min(rate, q->flow_max_rate); 475 if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) {
477 if (rate) { 476 rate = skb->sk->sk_pacing_rate ?: q->flow_default_rate;
478 u64 len = (u64)qdisc_pkt_len(skb) * NSEC_PER_SEC;
479
480 do_div(len, rate);
481 /* Since socket rate can change later,
482 * clamp the delay to 125 ms.
483 * TODO: maybe segment the too big skb, as in commit
484 * e43ac79a4bc ("sch_tbf: segment too big GSO packets")
485 */
486 if (unlikely(len > 125 * NSEC_PER_MSEC)) {
487 len = 125 * NSEC_PER_MSEC;
488 q->stat_pkts_too_long++;
489 }
490 477
491 f->time_next_packet = now + len; 478 rate = min(rate, q->flow_max_rate);
479 } else {
480 rate = q->flow_max_rate;
481 if (rate == ~0U)
482 goto out;
483 }
484 if (rate) {
485 u32 plen = max(qdisc_pkt_len(skb), q->quantum);
486 u64 len = (u64)plen * NSEC_PER_SEC;
487
488 do_div(len, rate);
489 /* Since socket rate can change later,
490 * clamp the delay to 125 ms.
491 * TODO: maybe segment the too big skb, as in commit
492 * e43ac79a4bc ("sch_tbf: segment too big GSO packets")
493 */
494 if (unlikely(len > 125 * NSEC_PER_MSEC)) {
495 len = 125 * NSEC_PER_MSEC;
496 q->stat_pkts_too_long++;
492 } 497 }
498
499 f->time_next_packet = now + len;
493 } 500 }
494out: 501out:
495 qdisc_bstats_update(sch, skb); 502 qdisc_bstats_update(sch, skb);