aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_fifo.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/sched/sch_fifo.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/sched/sch_fifo.c')
-rw-r--r--net/sched/sch_fifo.c60
1 files changed, 26 insertions, 34 deletions
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 5948bafa8ce2..66effe2da8e0 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -19,46 +19,30 @@
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 sk_buff *skb_head; 40 if (likely(skb_queue_len(&sch->q) < sch->limit))
50 struct fifo_sched_data *q = qdisc_priv(sch);
51
52 if (likely(skb_queue_len(&sch->q) < q->limit))
53 return qdisc_enqueue_tail(skb, sch); 41 return qdisc_enqueue_tail(skb, sch);
54 42
55 /* queue full, remove one skb to fulfill the limit */ 43 /* queue full, remove one skb to fulfill the limit */
56 skb_head = qdisc_dequeue_head(sch); 44 __qdisc_queue_drop_head(sch, &sch->q);
57 sch->bstats.bytes -= qdisc_pkt_len(skb_head);
58 sch->bstats.packets--;
59 sch->qstats.drops++; 45 sch->qstats.drops++;
60 kfree_skb(skb_head);
61
62 qdisc_enqueue_tail(skb, sch); 46 qdisc_enqueue_tail(skb, sch);
63 47
64 return NET_XMIT_CN; 48 return NET_XMIT_CN;
@@ -66,31 +50,40 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch)
66 50
67static int fifo_init(struct Qdisc *sch, struct nlattr *opt) 51static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
68{ 52{
69 struct fifo_sched_data *q = qdisc_priv(sch); 53 bool bypass;
54 bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
70 55
71 if (opt == NULL) { 56 if (opt == NULL) {
72 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1; 57 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
73 58
74 if (sch->ops == &bfifo_qdisc_ops) 59 if (is_bfifo)
75 limit *= psched_mtu(qdisc_dev(sch)); 60 limit *= psched_mtu(qdisc_dev(sch));
76 61
77 q->limit = limit; 62 sch->limit = limit;
78 } else { 63 } else {
79 struct tc_fifo_qopt *ctl = nla_data(opt); 64 struct tc_fifo_qopt *ctl = nla_data(opt);
80 65
81 if (nla_len(opt) < sizeof(*ctl)) 66 if (nla_len(opt) < sizeof(*ctl))
82 return -EINVAL; 67 return -EINVAL;
83 68
84 q->limit = ctl->limit; 69 sch->limit = ctl->limit;
85 } 70 }
86 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;
87 return 0; 81 return 0;
88} 82}
89 83
90static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) 84static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
91{ 85{
92 struct fifo_sched_data *q = qdisc_priv(sch); 86 struct tc_fifo_qopt opt = { .limit = sch->limit };
93 struct tc_fifo_qopt opt = { .limit = q->limit };
94 87
95 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); 88 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
96 return skb->len; 89 return skb->len;
@@ -101,7 +94,7 @@ nla_put_failure:
101 94
102struct Qdisc_ops pfifo_qdisc_ops __read_mostly = { 95struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
103 .id = "pfifo", 96 .id = "pfifo",
104 .priv_size = sizeof(struct fifo_sched_data), 97 .priv_size = 0,
105 .enqueue = pfifo_enqueue, 98 .enqueue = pfifo_enqueue,
106 .dequeue = qdisc_dequeue_head, 99 .dequeue = qdisc_dequeue_head,
107 .peek = qdisc_peek_head, 100 .peek = qdisc_peek_head,
@@ -116,7 +109,7 @@ EXPORT_SYMBOL(pfifo_qdisc_ops);
116 109
117struct Qdisc_ops bfifo_qdisc_ops __read_mostly = { 110struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
118 .id = "bfifo", 111 .id = "bfifo",
119 .priv_size = sizeof(struct fifo_sched_data), 112 .priv_size = 0,
120 .enqueue = bfifo_enqueue, 113 .enqueue = bfifo_enqueue,
121 .dequeue = qdisc_dequeue_head, 114 .dequeue = qdisc_dequeue_head,
122 .peek = qdisc_peek_head, 115 .peek = qdisc_peek_head,
@@ -131,7 +124,7 @@ EXPORT_SYMBOL(bfifo_qdisc_ops);
131 124
132struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = { 125struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
133 .id = "pfifo_head_drop", 126 .id = "pfifo_head_drop",
134 .priv_size = sizeof(struct fifo_sched_data), 127 .priv_size = 0,
135 .enqueue = pfifo_tail_enqueue, 128 .enqueue = pfifo_tail_enqueue,
136 .dequeue = qdisc_dequeue_head, 129 .dequeue = qdisc_dequeue_head,
137 .peek = qdisc_peek_head, 130 .peek = qdisc_peek_head,
@@ -172,8 +165,7 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
172 struct Qdisc *q; 165 struct Qdisc *q;
173 int err = -ENOMEM; 166 int err = -ENOMEM;
174 167
175 q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, 168 q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1));
176 ops, TC_H_MAKE(sch->handle, 1));
177 if (q) { 169 if (q) {
178 err = fifo_set_limit(q, limit); 170 err = fifo_set_limit(q, limit);
179 if (err < 0) { 171 if (err < 0) {