aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_fifo.c')
-rw-r--r--net/sched/sch_fifo.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index d468b479aa9..66effe2da8e 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -19,36 +19,25 @@
19 19
20/* 1 band FIFO pseudo-"scheduler" */ 20/* 1 band FIFO pseudo-"scheduler" */
21 21
22struct fifo_sched_data 22static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)
23{ 23{
24 u32 limit; 24 if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= sch->limit))
25};
26
27static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
28{
29 struct fifo_sched_data *q = qdisc_priv(sch);
30
31 if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= q->limit))
32 return qdisc_enqueue_tail(skb, sch); 25 return qdisc_enqueue_tail(skb, sch);
33 26
34 return qdisc_reshape_fail(skb, sch); 27 return qdisc_reshape_fail(skb, sch);
35} 28}
36 29
37static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) 30static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)
38{ 31{
39 struct fifo_sched_data *q = qdisc_priv(sch); 32 if (likely(skb_queue_len(&sch->q) < sch->limit))
40
41 if (likely(skb_queue_len(&sch->q) < q->limit))
42 return qdisc_enqueue_tail(skb, sch); 33 return qdisc_enqueue_tail(skb, sch);
43 34
44 return qdisc_reshape_fail(skb, sch); 35 return qdisc_reshape_fail(skb, sch);
45} 36}
46 37
47static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) 38static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)
48{ 39{
49 struct fifo_sched_data *q = qdisc_priv(sch); 40 if (likely(skb_queue_len(&sch->q) < sch->limit))
50
51 if (likely(skb_queue_len(&sch->q) < q->limit))
52 return qdisc_enqueue_tail(skb, sch); 41 return qdisc_enqueue_tail(skb, sch);
53 42
54 /* queue full, remove one skb to fulfill the limit */ 43 /* queue full, remove one skb to fulfill the limit */
@@ -61,31 +50,40 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch)
61 50
62static int fifo_init(struct Qdisc *sch, struct nlattr *opt) 51static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
63{ 52{
64 struct fifo_sched_data *q = qdisc_priv(sch); 53 bool bypass;
54 bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
65 55
66 if (opt == NULL) { 56 if (opt == NULL) {
67 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1; 57 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
68 58
69 if (sch->ops == &bfifo_qdisc_ops) 59 if (is_bfifo)
70 limit *= psched_mtu(qdisc_dev(sch)); 60 limit *= psched_mtu(qdisc_dev(sch));
71 61
72 q->limit = limit; 62 sch->limit = limit;
73 } else { 63 } else {
74 struct tc_fifo_qopt *ctl = nla_data(opt); 64 struct tc_fifo_qopt *ctl = nla_data(opt);
75 65
76 if (nla_len(opt) < sizeof(*ctl)) 66 if (nla_len(opt) < sizeof(*ctl))
77 return -EINVAL; 67 return -EINVAL;
78 68
79 q->limit = ctl->limit; 69 sch->limit = ctl->limit;
80 } 70 }
81 71
72 if (is_bfifo)
73 bypass = sch->limit >= psched_mtu(qdisc_dev(sch));
74 else
75 bypass = sch->limit >= 1;
76
77 if (bypass)
78 sch->flags |= TCQ_F_CAN_BYPASS;
79 else
80 sch->flags &= ~TCQ_F_CAN_BYPASS;
82 return 0; 81 return 0;
83} 82}
84 83
85static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) 84static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
86{ 85{
87 struct fifo_sched_data *q = qdisc_priv(sch); 86 struct tc_fifo_qopt opt = { .limit = sch->limit };
88 struct tc_fifo_qopt opt = { .limit = q->limit };
89 87
90 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); 88 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
91 return skb->len; 89 return skb->len;
@@ -96,7 +94,7 @@ nla_put_failure:
96 94
97struct Qdisc_ops pfifo_qdisc_ops __read_mostly = { 95struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
98 .id = "pfifo", 96 .id = "pfifo",
99 .priv_size = sizeof(struct fifo_sched_data), 97 .priv_size = 0,
100 .enqueue = pfifo_enqueue, 98 .enqueue = pfifo_enqueue,
101 .dequeue = qdisc_dequeue_head, 99 .dequeue = qdisc_dequeue_head,
102 .peek = qdisc_peek_head, 100 .peek = qdisc_peek_head,
@@ -111,7 +109,7 @@ EXPORT_SYMBOL(pfifo_qdisc_ops);
111 109
112struct Qdisc_ops bfifo_qdisc_ops __read_mostly = { 110struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
113 .id = "bfifo", 111 .id = "bfifo",
114 .priv_size = sizeof(struct fifo_sched_data), 112 .priv_size = 0,
115 .enqueue = bfifo_enqueue, 113 .enqueue = bfifo_enqueue,
116 .dequeue = qdisc_dequeue_head, 114 .dequeue = qdisc_dequeue_head,
117 .peek = qdisc_peek_head, 115 .peek = qdisc_peek_head,
@@ -126,7 +124,7 @@ EXPORT_SYMBOL(bfifo_qdisc_ops);
126 124
127struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = { 125struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
128 .id = "pfifo_head_drop", 126 .id = "pfifo_head_drop",
129 .priv_size = sizeof(struct fifo_sched_data), 127 .priv_size = 0,
130 .enqueue = pfifo_tail_enqueue, 128 .enqueue = pfifo_tail_enqueue,
131 .dequeue = qdisc_dequeue_head, 129 .dequeue = qdisc_dequeue_head,
132 .peek = qdisc_peek_head, 130 .peek = qdisc_peek_head,