aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_hfsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_hfsc.c')
-rw-r--r--net/sched/sch_hfsc.c64
1 files changed, 25 insertions, 39 deletions
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index c1e77da8cd0..45c31b1a4e1 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -184,7 +184,6 @@ struct hfsc_sched
184 struct rb_root eligible; /* eligible tree */ 184 struct rb_root eligible; /* eligible tree */
185 struct list_head droplist; /* active leaf class list (for 185 struct list_head droplist; /* active leaf class list (for
186 dropping) */ 186 dropping) */
187 struct sk_buff_head requeue; /* requeued packet */
188 struct qdisc_watchdog watchdog; /* watchdog timer */ 187 struct qdisc_watchdog watchdog; /* watchdog timer */
189}; 188};
190 189
@@ -880,28 +879,20 @@ set_passive(struct hfsc_class *cl)
880 */ 879 */
881} 880}
882 881
883/*
884 * hack to get length of first packet in queue.
885 */
886static unsigned int 882static unsigned int
887qdisc_peek_len(struct Qdisc *sch) 883qdisc_peek_len(struct Qdisc *sch)
888{ 884{
889 struct sk_buff *skb; 885 struct sk_buff *skb;
890 unsigned int len; 886 unsigned int len;
891 887
892 skb = sch->dequeue(sch); 888 skb = sch->ops->peek(sch);
893 if (skb == NULL) { 889 if (skb == NULL) {
894 if (net_ratelimit()) 890 if (net_ratelimit())
895 printk("qdisc_peek_len: non work-conserving qdisc ?\n"); 891 printk("qdisc_peek_len: non work-conserving qdisc ?\n");
896 return 0; 892 return 0;
897 } 893 }
898 len = qdisc_pkt_len(skb); 894 len = qdisc_pkt_len(skb);
899 if (unlikely(sch->ops->requeue(skb, sch) != NET_XMIT_SUCCESS)) { 895
900 if (net_ratelimit())
901 printk("qdisc_peek_len: failed to requeue\n");
902 qdisc_tree_decrease_qlen(sch, 1);
903 return 0;
904 }
905 return len; 896 return len;
906} 897}
907 898
@@ -1027,6 +1018,14 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1027 } 1018 }
1028 cur_time = psched_get_time(); 1019 cur_time = psched_get_time();
1029 1020
1021 if (tca[TCA_RATE]) {
1022 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1023 qdisc_root_sleeping_lock(sch),
1024 tca[TCA_RATE]);
1025 if (err)
1026 return err;
1027 }
1028
1030 sch_tree_lock(sch); 1029 sch_tree_lock(sch);
1031 if (rsc != NULL) 1030 if (rsc != NULL)
1032 hfsc_change_rsc(cl, rsc, cur_time); 1031 hfsc_change_rsc(cl, rsc, cur_time);
@@ -1043,10 +1042,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1043 } 1042 }
1044 sch_tree_unlock(sch); 1043 sch_tree_unlock(sch);
1045 1044
1046 if (tca[TCA_RATE])
1047 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1048 qdisc_root_sleeping_lock(sch),
1049 tca[TCA_RATE]);
1050 return 0; 1045 return 0;
1051 } 1046 }
1052 1047
@@ -1072,6 +1067,16 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1072 if (cl == NULL) 1067 if (cl == NULL)
1073 return -ENOBUFS; 1068 return -ENOBUFS;
1074 1069
1070 if (tca[TCA_RATE]) {
1071 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1072 qdisc_root_sleeping_lock(sch),
1073 tca[TCA_RATE]);
1074 if (err) {
1075 kfree(cl);
1076 return err;
1077 }
1078 }
1079
1075 if (rsc != NULL) 1080 if (rsc != NULL)
1076 hfsc_change_rsc(cl, rsc, 0); 1081 hfsc_change_rsc(cl, rsc, 0);
1077 if (fsc != NULL) 1082 if (fsc != NULL)
@@ -1102,9 +1107,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1102 1107
1103 qdisc_class_hash_grow(sch, &q->clhash); 1108 qdisc_class_hash_grow(sch, &q->clhash);
1104 1109
1105 if (tca[TCA_RATE])
1106 gen_new_estimator(&cl->bstats, &cl->rate_est,
1107 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1108 *arg = (unsigned long)cl; 1110 *arg = (unsigned long)cl;
1109 return 0; 1111 return 0;
1110} 1112}
@@ -1211,7 +1213,8 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1211 1213
1212 sch_tree_lock(sch); 1214 sch_tree_lock(sch);
1213 hfsc_purge_queue(sch, cl); 1215 hfsc_purge_queue(sch, cl);
1214 *old = xchg(&cl->qdisc, new); 1216 *old = cl->qdisc;
1217 cl->qdisc = new;
1215 sch_tree_unlock(sch); 1218 sch_tree_unlock(sch);
1216 return 0; 1219 return 0;
1217} 1220}
@@ -1440,7 +1443,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
1440 return err; 1443 return err;
1441 q->eligible = RB_ROOT; 1444 q->eligible = RB_ROOT;
1442 INIT_LIST_HEAD(&q->droplist); 1445 INIT_LIST_HEAD(&q->droplist);
1443 skb_queue_head_init(&q->requeue);
1444 1446
1445 q->root.cl_common.classid = sch->handle; 1447 q->root.cl_common.classid = sch->handle;
1446 q->root.refcnt = 1; 1448 q->root.refcnt = 1;
@@ -1525,7 +1527,6 @@ hfsc_reset_qdisc(struct Qdisc *sch)
1525 hlist_for_each_entry(cl, n, &q->clhash.hash[i], cl_common.hnode) 1527 hlist_for_each_entry(cl, n, &q->clhash.hash[i], cl_common.hnode)
1526 hfsc_reset_class(cl); 1528 hfsc_reset_class(cl);
1527 } 1529 }
1528 __skb_queue_purge(&q->requeue);
1529 q->eligible = RB_ROOT; 1530 q->eligible = RB_ROOT;
1530 INIT_LIST_HEAD(&q->droplist); 1531 INIT_LIST_HEAD(&q->droplist);
1531 qdisc_watchdog_cancel(&q->watchdog); 1532 qdisc_watchdog_cancel(&q->watchdog);
@@ -1550,7 +1551,6 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
1550 hfsc_destroy_class(sch, cl); 1551 hfsc_destroy_class(sch, cl);
1551 } 1552 }
1552 qdisc_class_hash_destroy(&q->clhash); 1553 qdisc_class_hash_destroy(&q->clhash);
1553 __skb_queue_purge(&q->requeue);
1554 qdisc_watchdog_cancel(&q->watchdog); 1554 qdisc_watchdog_cancel(&q->watchdog);
1555} 1555}
1556 1556
@@ -1574,7 +1574,7 @@ static int
1574hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 1574hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
1575{ 1575{
1576 struct hfsc_class *cl; 1576 struct hfsc_class *cl;
1577 int err; 1577 int uninitialized_var(err);
1578 1578
1579 cl = hfsc_classify(skb, sch, &err); 1579 cl = hfsc_classify(skb, sch, &err);
1580 if (cl == NULL) { 1580 if (cl == NULL) {
@@ -1617,8 +1617,6 @@ hfsc_dequeue(struct Qdisc *sch)
1617 1617
1618 if (sch->q.qlen == 0) 1618 if (sch->q.qlen == 0)
1619 return NULL; 1619 return NULL;
1620 if ((skb = __skb_dequeue(&q->requeue)))
1621 goto out;
1622 1620
1623 cur_time = psched_get_time(); 1621 cur_time = psched_get_time();
1624 1622
@@ -1642,7 +1640,7 @@ hfsc_dequeue(struct Qdisc *sch)
1642 } 1640 }
1643 } 1641 }
1644 1642
1645 skb = cl->qdisc->dequeue(cl->qdisc); 1643 skb = qdisc_dequeue_peeked(cl->qdisc);
1646 if (skb == NULL) { 1644 if (skb == NULL) {
1647 if (net_ratelimit()) 1645 if (net_ratelimit())
1648 printk("HFSC: Non-work-conserving qdisc ?\n"); 1646 printk("HFSC: Non-work-conserving qdisc ?\n");
@@ -1667,24 +1665,12 @@ hfsc_dequeue(struct Qdisc *sch)
1667 set_passive(cl); 1665 set_passive(cl);
1668 } 1666 }
1669 1667
1670 out:
1671 sch->flags &= ~TCQ_F_THROTTLED; 1668 sch->flags &= ~TCQ_F_THROTTLED;
1672 sch->q.qlen--; 1669 sch->q.qlen--;
1673 1670
1674 return skb; 1671 return skb;
1675} 1672}
1676 1673
1677static int
1678hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch)
1679{
1680 struct hfsc_sched *q = qdisc_priv(sch);
1681
1682 __skb_queue_head(&q->requeue, skb);
1683 sch->q.qlen++;
1684 sch->qstats.requeues++;
1685 return NET_XMIT_SUCCESS;
1686}
1687
1688static unsigned int 1674static unsigned int
1689hfsc_drop(struct Qdisc *sch) 1675hfsc_drop(struct Qdisc *sch)
1690{ 1676{
@@ -1735,7 +1721,7 @@ static struct Qdisc_ops hfsc_qdisc_ops __read_mostly = {
1735 .dump = hfsc_dump_qdisc, 1721 .dump = hfsc_dump_qdisc,
1736 .enqueue = hfsc_enqueue, 1722 .enqueue = hfsc_enqueue,
1737 .dequeue = hfsc_dequeue, 1723 .dequeue = hfsc_dequeue,
1738 .requeue = hfsc_requeue, 1724 .peek = qdisc_peek_dequeued,
1739 .drop = hfsc_drop, 1725 .drop = hfsc_drop,
1740 .cl_ops = &hfsc_class_ops, 1726 .cl_ops = &hfsc_class_ops,
1741 .priv_size = sizeof(struct hfsc_sched), 1727 .priv_size = sizeof(struct hfsc_sched),