diff options
Diffstat (limited to 'net/sched/sch_fifo.c')
| -rw-r--r-- | net/sched/sch_fifo.c | 60 | 
1 files changed, 27 insertions, 33 deletions
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 4dfecb0cba3..e15a9eb2908 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -19,46 +19,30 @@  /* 1 band FIFO pseudo-"scheduler" */ -struct fifo_sched_data +static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)  { -	u32 limit; -}; - -static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) -{ -	struct fifo_sched_data *q = qdisc_priv(sch); - -	if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= q->limit)) +	if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= sch->limit))  		return qdisc_enqueue_tail(skb, sch);  	return qdisc_reshape_fail(skb, sch);  } -static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) +static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)  { -	struct fifo_sched_data *q = qdisc_priv(sch); - -	if (likely(skb_queue_len(&sch->q) < q->limit)) +	if (likely(skb_queue_len(&sch->q) < sch->limit))  		return qdisc_enqueue_tail(skb, sch);  	return qdisc_reshape_fail(skb, sch);  } -static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) +static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)  { -	struct sk_buff *skb_head; -	struct fifo_sched_data *q = qdisc_priv(sch); - -	if (likely(skb_queue_len(&sch->q) < q->limit)) +	if (likely(skb_queue_len(&sch->q) < sch->limit))  		return qdisc_enqueue_tail(skb, sch);  	/* queue full, remove one skb to fulfill the limit */ -	skb_head = qdisc_dequeue_head(sch); -	sch->bstats.bytes -= qdisc_pkt_len(skb_head); -	sch->bstats.packets--; +	__qdisc_queue_drop_head(sch, &sch->q);  	sch->qstats.drops++; -	kfree_skb(skb_head); -  	qdisc_enqueue_tail(skb, sch);  	return NET_XMIT_CN; @@ -66,33 +50,43 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch)  static int fifo_init(struct Qdisc *sch, struct nlattr *opt)  { -	struct fifo_sched_data *q = qdisc_priv(sch); +	bool bypass; +	bool is_bfifo = sch->ops == &bfifo_qdisc_ops;  	if (opt == NULL) {  		u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1; -		if (sch->ops == &bfifo_qdisc_ops) +		if (is_bfifo)  			limit *= psched_mtu(qdisc_dev(sch)); -		q->limit = limit; +		sch->limit = limit;  	} else {  		struct tc_fifo_qopt *ctl = nla_data(opt);  		if (nla_len(opt) < sizeof(*ctl))  			return -EINVAL; -		q->limit = ctl->limit; +		sch->limit = ctl->limit;  	} +	if (is_bfifo) +		bypass = sch->limit >= psched_mtu(qdisc_dev(sch)); +	else +		bypass = sch->limit >= 1; + +	if (bypass) +		sch->flags |= TCQ_F_CAN_BYPASS; +	else +		sch->flags &= ~TCQ_F_CAN_BYPASS;  	return 0;  }  static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)  { -	struct fifo_sched_data *q = qdisc_priv(sch); -	struct tc_fifo_qopt opt = { .limit = q->limit }; +	struct tc_fifo_qopt opt = { .limit = sch->limit }; -	NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); +	if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) +		goto nla_put_failure;  	return skb->len;  nla_put_failure: @@ -101,7 +95,7 @@ nla_put_failure:  struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {  	.id		=	"pfifo", -	.priv_size	=	sizeof(struct fifo_sched_data), +	.priv_size	=	0,  	.enqueue	=	pfifo_enqueue,  	.dequeue	=	qdisc_dequeue_head,  	.peek		=	qdisc_peek_head, @@ -116,7 +110,7 @@ EXPORT_SYMBOL(pfifo_qdisc_ops);  struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {  	.id		=	"bfifo", -	.priv_size	=	sizeof(struct fifo_sched_data), +	.priv_size	=	0,  	.enqueue	=	bfifo_enqueue,  	.dequeue	=	qdisc_dequeue_head,  	.peek		=	qdisc_peek_head, @@ -131,7 +125,7 @@ EXPORT_SYMBOL(bfifo_qdisc_ops);  struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {  	.id		=	"pfifo_head_drop", -	.priv_size	=	sizeof(struct fifo_sched_data), +	.priv_size	=	0,  	.enqueue	=	pfifo_tail_enqueue,  	.dequeue	=	qdisc_dequeue_head,  	.peek		=	qdisc_peek_head,  | 
