diff options
author | Eric Dumazet <edumazet@google.com> | 2020-05-03 05:54:21 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-04 01:50:45 +0300 |
commit | c288b0ca86a0a49ad450cf2d76a9a70c2ca9e43f (patch) | |
tree | 7e8a7d42bd7420c3b372becdf0173a5e78355c4b /net/sched | |
parent | 82a0aa53b520edf50e08bad347d87d898de414eb (diff) | |
download | linux-c288b0ca86a0a49ad450cf2d76a9a70c2ca9e43f.tar.xz |
net_sched: sch_fq: do not call fq_peek() twice per packet
This refactors the code to not call fq_peek() from fq_dequeue_head()
since the caller can provide the skb.
Also rename fq_dequeue_head() to fq_dequeue_skb() because 'head' is
a bit vague, given the skb could come from t_root rb-tree.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_fq.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 53ec47ff8469..567df8fcaf70 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -384,19 +384,17 @@ static void fq_erase_head(struct Qdisc *sch, struct fq_flow *flow, } } -/* remove one skb from head of flow queue */ -static struct sk_buff *fq_dequeue_head(struct Qdisc *sch, struct fq_flow *flow) +/* Remove one skb from flow queue. + * This skb must be the return value of prior fq_peek(). + */ +static void fq_dequeue_skb(struct Qdisc *sch, struct fq_flow *flow, + struct sk_buff *skb) { - struct sk_buff *skb = fq_peek(flow); - - if (skb) { - fq_erase_head(sch, flow, skb); - skb_mark_not_on_list(skb); - flow->qlen--; - qdisc_qstats_backlog_dec(sch, skb); - sch->q.qlen--; - } - return skb; + fq_erase_head(sch, flow, skb); + skb_mark_not_on_list(skb); + flow->qlen--; + qdisc_qstats_backlog_dec(sch, skb); + sch->q.qlen--; } static void flow_queue_add(struct fq_flow *flow, struct sk_buff *skb) @@ -508,9 +506,11 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch) if (!sch->q.qlen) return NULL; - skb = fq_dequeue_head(sch, &q->internal); - if (skb) + skb = fq_peek(&q->internal); + if (unlikely(skb)) { + fq_dequeue_skb(sch, &q->internal, skb); goto out; + } now = ktime_get_ns(); fq_check_throttled(q, now); @@ -550,10 +550,8 @@ begin: INET_ECN_set_ce(skb); q->stat_ce_mark++; } - } - - skb = fq_dequeue_head(sch, f); - if (!skb) { + fq_dequeue_skb(sch, f, skb); + } else { head->first = f->next; /* force a pass through old_flows to prevent starvation */ if ((head == &q->new_flows) && q->old_flows.first) { |