sch_htb.c (d88c305a03c37a95c4b27e1a0c2e387bb7ce80df) sch_htb.c (1e90474c377e92db7262a8968a45c1dd980ca9e5)
1/*
2 * net/sched/sch_htb.c Hierarchical token bucket, feed tree version
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 978 unchanged lines hidden (view full) ---

987 memset(q->row, 0, sizeof(q->row));
988 memset(q->row_mask, 0, sizeof(q->row_mask));
989 memset(q->wait_pq, 0, sizeof(q->wait_pq));
990 memset(q->ptr, 0, sizeof(q->ptr));
991 for (i = 0; i < TC_HTB_NUMPRIO; i++)
992 INIT_LIST_HEAD(q->drops + i);
993}
994
1/*
2 * net/sched/sch_htb.c Hierarchical token bucket, feed tree version
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 978 unchanged lines hidden (view full) ---

987 memset(q->row, 0, sizeof(q->row));
988 memset(q->row_mask, 0, sizeof(q->row_mask));
989 memset(q->wait_pq, 0, sizeof(q->wait_pq));
990 memset(q->ptr, 0, sizeof(q->ptr));
991 for (i = 0; i < TC_HTB_NUMPRIO; i++)
992 INIT_LIST_HEAD(q->drops + i);
993}
994
995static int htb_init(struct Qdisc *sch, struct rtattr *opt)
995static int htb_init(struct Qdisc *sch, struct nlattr *opt)
996{
997 struct htb_sched *q = qdisc_priv(sch);
996{
997 struct htb_sched *q = qdisc_priv(sch);
998 struct rtattr *tb[TCA_HTB_INIT];
998 struct nlattr *tb[TCA_HTB_INIT + 1];
999 struct tc_htb_glob *gopt;
1000 int i;
999 struct tc_htb_glob *gopt;
1000 int i;
1001 if (!opt || rtattr_parse_nested(tb, TCA_HTB_INIT, opt) ||
1002 tb[TCA_HTB_INIT - 1] == NULL ||
1003 RTA_PAYLOAD(tb[TCA_HTB_INIT - 1]) < sizeof(*gopt)) {
1001 if (!opt || nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL) ||
1002 tb[TCA_HTB_INIT] == NULL ||
1003 nla_len(tb[TCA_HTB_INIT]) < sizeof(*gopt)) {
1004 printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
1005 return -EINVAL;
1006 }
1004 printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
1005 return -EINVAL;
1006 }
1007 gopt = RTA_DATA(tb[TCA_HTB_INIT - 1]);
1007 gopt = nla_data(tb[TCA_HTB_INIT]);
1008 if (gopt->version != HTB_VER >> 16) {
1009 printk(KERN_ERR
1010 "HTB: need tc/htb version %d (minor is %d), you have %d\n",
1011 HTB_VER >> 16, HTB_VER & 0xffff, gopt->version);
1012 return -EINVAL;
1013 }
1014
1015 INIT_LIST_HEAD(&q->root);

--- 15 unchanged lines hidden (view full) ---

1031
1032 return 0;
1033}
1034
1035static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1036{
1037 struct htb_sched *q = qdisc_priv(sch);
1038 unsigned char *b = skb_tail_pointer(skb);
1008 if (gopt->version != HTB_VER >> 16) {
1009 printk(KERN_ERR
1010 "HTB: need tc/htb version %d (minor is %d), you have %d\n",
1011 HTB_VER >> 16, HTB_VER & 0xffff, gopt->version);
1012 return -EINVAL;
1013 }
1014
1015 INIT_LIST_HEAD(&q->root);

--- 15 unchanged lines hidden (view full) ---

1031
1032 return 0;
1033}
1034
1035static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1036{
1037 struct htb_sched *q = qdisc_priv(sch);
1038 unsigned char *b = skb_tail_pointer(skb);
1039 struct rtattr *rta;
1039 struct nlattr *nla;
1040 struct tc_htb_glob gopt;
1041 spin_lock_bh(&sch->dev->queue_lock);
1042 gopt.direct_pkts = q->direct_pkts;
1043
1044 gopt.version = HTB_VER;
1045 gopt.rate2quantum = q->rate2quantum;
1046 gopt.defcls = q->defcls;
1047 gopt.debug = 0;
1040 struct tc_htb_glob gopt;
1041 spin_lock_bh(&sch->dev->queue_lock);
1042 gopt.direct_pkts = q->direct_pkts;
1043
1044 gopt.version = HTB_VER;
1045 gopt.rate2quantum = q->rate2quantum;
1046 gopt.defcls = q->defcls;
1047 gopt.debug = 0;
1048 rta = (struct rtattr *)b;
1049 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1050 RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
1051 rta->rta_len = skb_tail_pointer(skb) - b;
1048 nla = (struct nlattr *)b;
1049 NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
1050 NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
1051 nla->nla_len = skb_tail_pointer(skb) - b;
1052 spin_unlock_bh(&sch->dev->queue_lock);
1053 return skb->len;
1052 spin_unlock_bh(&sch->dev->queue_lock);
1053 return skb->len;
1054rtattr_failure:
1054nla_put_failure:
1055 spin_unlock_bh(&sch->dev->queue_lock);
1056 nlmsg_trim(skb, skb_tail_pointer(skb));
1057 return -1;
1058}
1059
1060static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1061 struct sk_buff *skb, struct tcmsg *tcm)
1062{
1063 struct htb_class *cl = (struct htb_class *)arg;
1064 unsigned char *b = skb_tail_pointer(skb);
1055 spin_unlock_bh(&sch->dev->queue_lock);
1056 nlmsg_trim(skb, skb_tail_pointer(skb));
1057 return -1;
1058}
1059
1060static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1061 struct sk_buff *skb, struct tcmsg *tcm)
1062{
1063 struct htb_class *cl = (struct htb_class *)arg;
1064 unsigned char *b = skb_tail_pointer(skb);
1065 struct rtattr *rta;
1065 struct nlattr *nla;
1066 struct tc_htb_opt opt;
1067
1068 spin_lock_bh(&sch->dev->queue_lock);
1069 tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
1070 tcm->tcm_handle = cl->classid;
1071 if (!cl->level && cl->un.leaf.q)
1072 tcm->tcm_info = cl->un.leaf.q->handle;
1073
1066 struct tc_htb_opt opt;
1067
1068 spin_lock_bh(&sch->dev->queue_lock);
1069 tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
1070 tcm->tcm_handle = cl->classid;
1071 if (!cl->level && cl->un.leaf.q)
1072 tcm->tcm_info = cl->un.leaf.q->handle;
1073
1074 rta = (struct rtattr *)b;
1075 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1074 nla = (struct nlattr *)b;
1075 NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
1076
1077 memset(&opt, 0, sizeof(opt));
1078
1079 opt.rate = cl->rate->rate;
1080 opt.buffer = cl->buffer;
1081 opt.ceil = cl->ceil->rate;
1082 opt.cbuffer = cl->cbuffer;
1083 opt.quantum = cl->un.leaf.quantum;
1084 opt.prio = cl->un.leaf.prio;
1085 opt.level = cl->level;
1076
1077 memset(&opt, 0, sizeof(opt));
1078
1079 opt.rate = cl->rate->rate;
1080 opt.buffer = cl->buffer;
1081 opt.ceil = cl->ceil->rate;
1082 opt.cbuffer = cl->cbuffer;
1083 opt.quantum = cl->un.leaf.quantum;
1084 opt.prio = cl->un.leaf.prio;
1085 opt.level = cl->level;
1086 RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1087 rta->rta_len = skb_tail_pointer(skb) - b;
1086 NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1087 nla->nla_len = skb_tail_pointer(skb) - b;
1088 spin_unlock_bh(&sch->dev->queue_lock);
1089 return skb->len;
1088 spin_unlock_bh(&sch->dev->queue_lock);
1089 return skb->len;
1090rtattr_failure:
1090nla_put_failure:
1091 spin_unlock_bh(&sch->dev->queue_lock);
1092 nlmsg_trim(skb, b);
1093 return -1;
1094}
1095
1096static int
1097htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
1098{

--- 186 unchanged lines hidden (view full) ---

1285{
1286 struct htb_class *cl = (struct htb_class *)arg;
1287
1288 if (--cl->refcnt == 0)
1289 htb_destroy_class(sch, cl);
1290}
1291
1292static int htb_change_class(struct Qdisc *sch, u32 classid,
1091 spin_unlock_bh(&sch->dev->queue_lock);
1092 nlmsg_trim(skb, b);
1093 return -1;
1094}
1095
1096static int
1097htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
1098{

--- 186 unchanged lines hidden (view full) ---

1285{
1286 struct htb_class *cl = (struct htb_class *)arg;
1287
1288 if (--cl->refcnt == 0)
1289 htb_destroy_class(sch, cl);
1290}
1291
1292static int htb_change_class(struct Qdisc *sch, u32 classid,
1293 u32 parentid, struct rtattr **tca,
1293 u32 parentid, struct nlattr **tca,
1294 unsigned long *arg)
1295{
1296 int err = -EINVAL;
1297 struct htb_sched *q = qdisc_priv(sch);
1298 struct htb_class *cl = (struct htb_class *)*arg, *parent;
1294 unsigned long *arg)
1295{
1296 int err = -EINVAL;
1297 struct htb_sched *q = qdisc_priv(sch);
1298 struct htb_class *cl = (struct htb_class *)*arg, *parent;
1299 struct rtattr *opt = tca[TCA_OPTIONS - 1];
1299 struct nlattr *opt = tca[TCA_OPTIONS];
1300 struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
1300 struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
1301 struct rtattr *tb[TCA_HTB_RTAB];
1301 struct nlattr *tb[TCA_HTB_RTAB + 1];
1302 struct tc_htb_opt *hopt;
1303
1304 /* extract all subattrs from opt attr */
1302 struct tc_htb_opt *hopt;
1303
1304 /* extract all subattrs from opt attr */
1305 if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) ||
1306 tb[TCA_HTB_PARMS - 1] == NULL ||
1307 RTA_PAYLOAD(tb[TCA_HTB_PARMS - 1]) < sizeof(*hopt))
1305 if (!opt || nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL) ||
1306 tb[TCA_HTB_PARMS] == NULL ||
1307 nla_len(tb[TCA_HTB_PARMS]) < sizeof(*hopt))
1308 goto failure;
1309
1310 parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch);
1311
1308 goto failure;
1309
1310 parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch);
1311
1312 hopt = RTA_DATA(tb[TCA_HTB_PARMS - 1]);
1312 hopt = nla_data(tb[TCA_HTB_PARMS]);
1313
1313
1314 rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB - 1]);
1315 ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB - 1]);
1314 rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]);
1315 ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]);
1316 if (!rtab || !ctab)
1317 goto failure;
1318
1319 if (!cl) { /* new class */
1320 struct Qdisc *new_q;
1321 int prio;
1322 struct {
1316 if (!rtab || !ctab)
1317 goto failure;
1318
1319 if (!cl) { /* new class */
1320 struct Qdisc *new_q;
1321 int prio;
1322 struct {
1323 struct rtattr rta;
1323 struct nlattr nla;
1324 struct gnet_estimator opt;
1325 } est = {
1324 struct gnet_estimator opt;
1325 } est = {
1326 .rta = {
1327 .rta_len = RTA_LENGTH(sizeof(est.opt)),
1328 .rta_type = TCA_RATE,
1326 .nla = {
1327 .nla_len = nla_attr_size(sizeof(est.opt)),
1328 .nla_type = TCA_RATE,
1329 },
1330 .opt = {
1331 /* 4s interval, 16s averaging constant */
1332 .interval = 2,
1333 .ewma_log = 2,
1334 },
1335 };
1336

--- 8 unchanged lines hidden (view full) ---

1345 goto failure;
1346 }
1347 err = -ENOBUFS;
1348 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
1349 goto failure;
1350
1351 gen_new_estimator(&cl->bstats, &cl->rate_est,
1352 &sch->dev->queue_lock,
1329 },
1330 .opt = {
1331 /* 4s interval, 16s averaging constant */
1332 .interval = 2,
1333 .ewma_log = 2,
1334 },
1335 };
1336

--- 8 unchanged lines hidden (view full) ---

1345 goto failure;
1346 }
1347 err = -ENOBUFS;
1348 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
1349 goto failure;
1350
1351 gen_new_estimator(&cl->bstats, &cl->rate_est,
1352 &sch->dev->queue_lock,
1353 tca[TCA_RATE-1] ? : &est.rta);
1353 tca[TCA_RATE] ? : &est.nla);
1354 cl->refcnt = 1;
1355 INIT_LIST_HEAD(&cl->sibling);
1356 INIT_HLIST_NODE(&cl->hlist);
1357 INIT_LIST_HEAD(&cl->children);
1358 INIT_LIST_HEAD(&cl->un.leaf.drop_list);
1359 RB_CLEAR_NODE(&cl->pq_node);
1360
1361 for (prio = 0; prio < TC_HTB_NUMPRIO; prio++)

--- 36 unchanged lines hidden (view full) ---

1398 cl->t_c = psched_get_time();
1399 cl->cmode = HTB_CAN_SEND;
1400
1401 /* attach to the hash list and parent's family */
1402 hlist_add_head(&cl->hlist, q->hash + htb_hash(classid));
1403 list_add_tail(&cl->sibling,
1404 parent ? &parent->children : &q->root);
1405 } else {
1354 cl->refcnt = 1;
1355 INIT_LIST_HEAD(&cl->sibling);
1356 INIT_HLIST_NODE(&cl->hlist);
1357 INIT_LIST_HEAD(&cl->children);
1358 INIT_LIST_HEAD(&cl->un.leaf.drop_list);
1359 RB_CLEAR_NODE(&cl->pq_node);
1360
1361 for (prio = 0; prio < TC_HTB_NUMPRIO; prio++)

--- 36 unchanged lines hidden (view full) ---

1398 cl->t_c = psched_get_time();
1399 cl->cmode = HTB_CAN_SEND;
1400
1401 /* attach to the hash list and parent's family */
1402 hlist_add_head(&cl->hlist, q->hash + htb_hash(classid));
1403 list_add_tail(&cl->sibling,
1404 parent ? &parent->children : &q->root);
1405 } else {
1406 if (tca[TCA_RATE-1])
1406 if (tca[TCA_RATE])
1407 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1408 &sch->dev->queue_lock,
1407 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1408 &sch->dev->queue_lock,
1409 tca[TCA_RATE-1]);
1409 tca[TCA_RATE]);
1410 sch_tree_lock(sch);
1411 }
1412
1413 /* it used to be a nasty bug here, we have to check that node
1414 is really leaf before changing cl->un.leaf ! */
1415 if (!cl->level) {
1416 cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
1417 if (!hopt->quantum && cl->un.leaf.quantum < 1000) {

--- 155 unchanged lines hidden ---
1410 sch_tree_lock(sch);
1411 }
1412
1413 /* it used to be a nasty bug here, we have to check that node
1414 is really leaf before changing cl->un.leaf ! */
1415 if (!cl->level) {
1416 cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
1417 if (!hopt->quantum && cl->un.leaf.quantum < 1000) {

--- 155 unchanged lines hidden ---