Commit c288b0ca authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 82a0aa53
Loading
Loading
Loading
Loading
+16 −18
Original line number Original line Diff line number Diff line
@@ -384,20 +384,18 @@ static void fq_erase_head(struct Qdisc *sch, struct fq_flow *flow,
	}
	}
}
}


/* remove one skb from head of flow queue */
/* Remove one skb from flow queue.
static struct sk_buff *fq_dequeue_head(struct Qdisc *sch, struct fq_flow *flow)
 * 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);
	fq_erase_head(sch, flow, skb);
	skb_mark_not_on_list(skb);
	skb_mark_not_on_list(skb);
	flow->qlen--;
	flow->qlen--;
	qdisc_qstats_backlog_dec(sch, skb);
	qdisc_qstats_backlog_dec(sch, skb);
	sch->q.qlen--;
	sch->q.qlen--;
}
}
	return skb;
}


static void flow_queue_add(struct fq_flow *flow, struct sk_buff *skb)
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)
	if (!sch->q.qlen)
		return NULL;
		return NULL;


	skb = fq_dequeue_head(sch, &q->internal);
	skb = fq_peek(&q->internal);
	if (skb)
	if (unlikely(skb)) {
		fq_dequeue_skb(sch, &q->internal, skb);
		goto out;
		goto out;
	}


	now = ktime_get_ns();
	now = ktime_get_ns();
	fq_check_throttled(q, now);
	fq_check_throttled(q, now);
@@ -550,10 +550,8 @@ begin:
			INET_ECN_set_ce(skb);
			INET_ECN_set_ce(skb);
			q->stat_ce_mark++;
			q->stat_ce_mark++;
		}
		}
	}
		fq_dequeue_skb(sch, f, skb);

	} else {
	skb = fq_dequeue_head(sch, f);
	if (!skb) {
		head->first = f->next;
		head->first = f->next;
		/* force a pass through old_flows to prevent starvation */
		/* force a pass through old_flows to prevent starvation */
		if ((head == &q->new_flows) && q->old_flows.first) {
		if ((head == &q->new_flows) && q->old_flows.first) {