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 --- |