aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_prio.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_prio.c')
-rw-r--r--net/sched/sch_prio.c50
1 files changed, 19 insertions, 31 deletions
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 504a78cdb718..94cecef70145 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -93,34 +93,20 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
93 return ret; 93 return ret;
94} 94}
95 95
96 96static struct sk_buff *prio_peek(struct Qdisc *sch)
97static int
98prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
99{ 97{
100 struct Qdisc *qdisc; 98 struct prio_sched_data *q = qdisc_priv(sch);
101 int ret; 99 int prio;
102
103 qdisc = prio_classify(skb, sch, &ret);
104#ifdef CONFIG_NET_CLS_ACT
105 if (qdisc == NULL) {
106 if (ret & __NET_XMIT_BYPASS)
107 sch->qstats.drops++;
108 kfree_skb(skb);
109 return ret;
110 }
111#endif
112 100
113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) { 101 for (prio = 0; prio < q->bands; prio++) {
114 sch->q.qlen++; 102 struct Qdisc *qdisc = q->queues[prio];
115 sch->qstats.requeues++; 103 struct sk_buff *skb = qdisc->ops->peek(qdisc);
116 return NET_XMIT_SUCCESS; 104 if (skb)
105 return skb;
117 } 106 }
118 if (net_xmit_drop_count(ret)) 107 return NULL;
119 sch->qstats.drops++;
120 return ret;
121} 108}
122 109
123
124static struct sk_buff *prio_dequeue(struct Qdisc* sch) 110static struct sk_buff *prio_dequeue(struct Qdisc* sch)
125{ 111{
126 struct prio_sched_data *q = qdisc_priv(sch); 112 struct prio_sched_data *q = qdisc_priv(sch);
@@ -201,7 +187,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
201 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); 187 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
202 188
203 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { 189 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
204 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); 190 struct Qdisc *child = q->queues[i];
191 q->queues[i] = &noop_qdisc;
205 if (child != &noop_qdisc) { 192 if (child != &noop_qdisc) {
206 qdisc_tree_decrease_qlen(child, child->q.qlen); 193 qdisc_tree_decrease_qlen(child, child->q.qlen);
207 qdisc_destroy(child); 194 qdisc_destroy(child);
@@ -211,18 +198,19 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
211 198
212 for (i=0; i<q->bands; i++) { 199 for (i=0; i<q->bands; i++) {
213 if (q->queues[i] == &noop_qdisc) { 200 if (q->queues[i] == &noop_qdisc) {
214 struct Qdisc *child; 201 struct Qdisc *child, *old;
215 child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, 202 child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
216 &pfifo_qdisc_ops, 203 &pfifo_qdisc_ops,
217 TC_H_MAKE(sch->handle, i + 1)); 204 TC_H_MAKE(sch->handle, i + 1));
218 if (child) { 205 if (child) {
219 sch_tree_lock(sch); 206 sch_tree_lock(sch);
220 child = xchg(&q->queues[i], child); 207 old = q->queues[i];
208 q->queues[i] = child;
221 209
222 if (child != &noop_qdisc) { 210 if (old != &noop_qdisc) {
223 qdisc_tree_decrease_qlen(child, 211 qdisc_tree_decrease_qlen(old,
224 child->q.qlen); 212 old->q.qlen);
225 qdisc_destroy(child); 213 qdisc_destroy(old);
226 } 214 }
227 sch_tree_unlock(sch); 215 sch_tree_unlock(sch);
228 } 216 }
@@ -421,7 +409,7 @@ static struct Qdisc_ops prio_qdisc_ops __read_mostly = {
421 .priv_size = sizeof(struct prio_sched_data), 409 .priv_size = sizeof(struct prio_sched_data),
422 .enqueue = prio_enqueue, 410 .enqueue = prio_enqueue,
423 .dequeue = prio_dequeue, 411 .dequeue = prio_dequeue,
424 .requeue = prio_requeue, 412 .peek = prio_peek,
425 .drop = prio_drop, 413 .drop = prio_drop,
426 .init = prio_init, 414 .init = prio_init,
427 .reset = prio_reset, 415 .reset = prio_reset,