sch_hfsc.c (20fea08b5fb639c4c175b5c74a2bb346c5c5bc2e) | sch_hfsc.c (1e90474c377e92db7262a8968a45c1dd980ca9e5) |
---|---|
1/* 2 * Copyright (c) 2003 Patrick McHardy, <kaber@trash.net> 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 2 7 * of the License, or (at your option) any later version. 8 * --- 974 unchanged lines hidden (view full) --- 983{ 984 sc2isc(usc, &cl->cl_usc); 985 rtsc_init(&cl->cl_ulimit, &cl->cl_usc, cur_time, cl->cl_total); 986 cl->cl_flags |= HFSC_USC; 987} 988 989static int 990hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 1/* 2 * Copyright (c) 2003 Patrick McHardy, <kaber@trash.net> 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 2 7 * of the License, or (at your option) any later version. 8 * --- 974 unchanged lines hidden (view full) --- 983{ 984 sc2isc(usc, &cl->cl_usc); 985 rtsc_init(&cl->cl_ulimit, &cl->cl_usc, cur_time, cl->cl_total); 986 cl->cl_flags |= HFSC_USC; 987} 988 989static int 990hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
991 struct rtattr **tca, unsigned long *arg) | 991 struct nlattr **tca, unsigned long *arg) |
992{ 993 struct hfsc_sched *q = qdisc_priv(sch); 994 struct hfsc_class *cl = (struct hfsc_class *)*arg; 995 struct hfsc_class *parent = NULL; | 992{ 993 struct hfsc_sched *q = qdisc_priv(sch); 994 struct hfsc_class *cl = (struct hfsc_class *)*arg; 995 struct hfsc_class *parent = NULL; |
996 struct rtattr *opt = tca[TCA_OPTIONS-1]; 997 struct rtattr *tb[TCA_HFSC_MAX]; | 996 struct nlattr *opt = tca[TCA_OPTIONS]; 997 struct nlattr *tb[TCA_HFSC_MAX + 1]; |
998 struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL; 999 u64 cur_time; 1000 | 998 struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL; 999 u64 cur_time; 1000 |
1001 if (opt == NULL || rtattr_parse_nested(tb, TCA_HFSC_MAX, opt)) | 1001 if (opt == NULL || nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL)) |
1002 return -EINVAL; 1003 | 1002 return -EINVAL; 1003 |
1004 if (tb[TCA_HFSC_RSC-1]) { 1005 if (RTA_PAYLOAD(tb[TCA_HFSC_RSC-1]) < sizeof(*rsc)) | 1004 if (tb[TCA_HFSC_RSC]) { 1005 if (nla_len(tb[TCA_HFSC_RSC]) < sizeof(*rsc)) |
1006 return -EINVAL; | 1006 return -EINVAL; |
1007 rsc = RTA_DATA(tb[TCA_HFSC_RSC-1]); | 1007 rsc = nla_data(tb[TCA_HFSC_RSC]); |
1008 if (rsc->m1 == 0 && rsc->m2 == 0) 1009 rsc = NULL; 1010 } 1011 | 1008 if (rsc->m1 == 0 && rsc->m2 == 0) 1009 rsc = NULL; 1010 } 1011 |
1012 if (tb[TCA_HFSC_FSC-1]) { 1013 if (RTA_PAYLOAD(tb[TCA_HFSC_FSC-1]) < sizeof(*fsc)) | 1012 if (tb[TCA_HFSC_FSC]) { 1013 if (nla_len(tb[TCA_HFSC_FSC]) < sizeof(*fsc)) |
1014 return -EINVAL; | 1014 return -EINVAL; |
1015 fsc = RTA_DATA(tb[TCA_HFSC_FSC-1]); | 1015 fsc = nla_data(tb[TCA_HFSC_FSC]); |
1016 if (fsc->m1 == 0 && fsc->m2 == 0) 1017 fsc = NULL; 1018 } 1019 | 1016 if (fsc->m1 == 0 && fsc->m2 == 0) 1017 fsc = NULL; 1018 } 1019 |
1020 if (tb[TCA_HFSC_USC-1]) { 1021 if (RTA_PAYLOAD(tb[TCA_HFSC_USC-1]) < sizeof(*usc)) | 1020 if (tb[TCA_HFSC_USC]) { 1021 if (nla_len(tb[TCA_HFSC_USC]) < sizeof(*usc)) |
1022 return -EINVAL; | 1022 return -EINVAL; |
1023 usc = RTA_DATA(tb[TCA_HFSC_USC-1]); | 1023 usc = nla_data(tb[TCA_HFSC_USC]); |
1024 if (usc->m1 == 0 && usc->m2 == 0) 1025 usc = NULL; 1026 } 1027 1028 if (cl != NULL) { 1029 if (parentid) { 1030 if (cl->cl_parent && cl->cl_parent->classid != parentid) 1031 return -EINVAL; --- 13 unchanged lines hidden (view full) --- 1045 if (cl->qdisc->q.qlen != 0) { 1046 if (cl->cl_flags & HFSC_RSC) 1047 update_ed(cl, qdisc_peek_len(cl->qdisc)); 1048 if (cl->cl_flags & HFSC_FSC) 1049 update_vf(cl, 0, cur_time); 1050 } 1051 sch_tree_unlock(sch); 1052 | 1024 if (usc->m1 == 0 && usc->m2 == 0) 1025 usc = NULL; 1026 } 1027 1028 if (cl != NULL) { 1029 if (parentid) { 1030 if (cl->cl_parent && cl->cl_parent->classid != parentid) 1031 return -EINVAL; --- 13 unchanged lines hidden (view full) --- 1045 if (cl->qdisc->q.qlen != 0) { 1046 if (cl->cl_flags & HFSC_RSC) 1047 update_ed(cl, qdisc_peek_len(cl->qdisc)); 1048 if (cl->cl_flags & HFSC_FSC) 1049 update_vf(cl, 0, cur_time); 1050 } 1051 sch_tree_unlock(sch); 1052 |
1053 if (tca[TCA_RATE-1]) | 1053 if (tca[TCA_RATE]) |
1054 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1055 &sch->dev->queue_lock, | 1054 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1055 &sch->dev->queue_lock, |
1056 tca[TCA_RATE-1]); | 1056 tca[TCA_RATE]); |
1057 return 0; 1058 } 1059 1060 if (parentid == TC_H_ROOT) 1061 return -EEXIST; 1062 1063 parent = &q->root; 1064 if (parentid) { --- 36 unchanged lines hidden (view full) --- 1101 list_add_tail(&cl->hlist, &q->clhash[hfsc_hash(classid)]); 1102 list_add_tail(&cl->siblings, &parent->children); 1103 if (parent->level == 0) 1104 hfsc_purge_queue(sch, parent); 1105 hfsc_adjust_levels(parent); 1106 cl->cl_pcvtoff = parent->cl_cvtoff; 1107 sch_tree_unlock(sch); 1108 | 1057 return 0; 1058 } 1059 1060 if (parentid == TC_H_ROOT) 1061 return -EEXIST; 1062 1063 parent = &q->root; 1064 if (parentid) { --- 36 unchanged lines hidden (view full) --- 1101 list_add_tail(&cl->hlist, &q->clhash[hfsc_hash(classid)]); 1102 list_add_tail(&cl->siblings, &parent->children); 1103 if (parent->level == 0) 1104 hfsc_purge_queue(sch, parent); 1105 hfsc_adjust_levels(parent); 1106 cl->cl_pcvtoff = parent->cl_cvtoff; 1107 sch_tree_unlock(sch); 1108 |
1109 if (tca[TCA_RATE-1]) | 1109 if (tca[TCA_RATE]) |
1110 gen_new_estimator(&cl->bstats, &cl->rate_est, | 1110 gen_new_estimator(&cl->bstats, &cl->rate_est, |
1111 &sch->dev->queue_lock, tca[TCA_RATE-1]); | 1111 &sch->dev->queue_lock, tca[TCA_RATE]); |
1112 *arg = (unsigned long)cl; 1113 return 0; 1114} 1115 1116static void 1117hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) 1118{ 1119 struct hfsc_sched *q = qdisc_priv(sch); --- 179 unchanged lines hidden (view full) --- 1299static int 1300hfsc_dump_sc(struct sk_buff *skb, int attr, struct internal_sc *sc) 1301{ 1302 struct tc_service_curve tsc; 1303 1304 tsc.m1 = sm2m(sc->sm1); 1305 tsc.d = dx2d(sc->dx); 1306 tsc.m2 = sm2m(sc->sm2); | 1112 *arg = (unsigned long)cl; 1113 return 0; 1114} 1115 1116static void 1117hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) 1118{ 1119 struct hfsc_sched *q = qdisc_priv(sch); --- 179 unchanged lines hidden (view full) --- 1299static int 1300hfsc_dump_sc(struct sk_buff *skb, int attr, struct internal_sc *sc) 1301{ 1302 struct tc_service_curve tsc; 1303 1304 tsc.m1 = sm2m(sc->sm1); 1305 tsc.d = dx2d(sc->dx); 1306 tsc.m2 = sm2m(sc->sm2); |
1307 RTA_PUT(skb, attr, sizeof(tsc), &tsc); | 1307 NLA_PUT(skb, attr, sizeof(tsc), &tsc); |
1308 1309 return skb->len; 1310 | 1308 1309 return skb->len; 1310 |
1311 rtattr_failure: | 1311 nla_put_failure: |
1312 return -1; 1313} 1314 1315static inline int 1316hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl) 1317{ 1318 if ((cl->cl_flags & HFSC_RSC) && 1319 (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0)) | 1312 return -1; 1313} 1314 1315static inline int 1316hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl) 1317{ 1318 if ((cl->cl_flags & HFSC_RSC) && 1319 (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0)) |
1320 goto rtattr_failure; | 1320 goto nla_put_failure; |
1321 1322 if ((cl->cl_flags & HFSC_FSC) && 1323 (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0)) | 1321 1322 if ((cl->cl_flags & HFSC_FSC) && 1323 (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0)) |
1324 goto rtattr_failure; | 1324 goto nla_put_failure; |
1325 1326 if ((cl->cl_flags & HFSC_USC) && 1327 (hfsc_dump_sc(skb, TCA_HFSC_USC, &cl->cl_usc) < 0)) | 1325 1326 if ((cl->cl_flags & HFSC_USC) && 1327 (hfsc_dump_sc(skb, TCA_HFSC_USC, &cl->cl_usc) < 0)) |
1328 goto rtattr_failure; | 1328 goto nla_put_failure; |
1329 1330 return skb->len; 1331 | 1329 1330 return skb->len; 1331 |
1332 rtattr_failure: | 1332 nla_put_failure: |
1333 return -1; 1334} 1335 1336static int 1337hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, 1338 struct tcmsg *tcm) 1339{ 1340 struct hfsc_class *cl = (struct hfsc_class *)arg; 1341 unsigned char *b = skb_tail_pointer(skb); | 1333 return -1; 1334} 1335 1336static int 1337hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, 1338 struct tcmsg *tcm) 1339{ 1340 struct hfsc_class *cl = (struct hfsc_class *)arg; 1341 unsigned char *b = skb_tail_pointer(skb); |
1342 struct rtattr *rta = (struct rtattr *)b; | 1342 struct nlattr *nla = (struct nlattr *)b; |
1343 1344 tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT; 1345 tcm->tcm_handle = cl->classid; 1346 if (cl->level == 0) 1347 tcm->tcm_info = cl->qdisc->handle; 1348 | 1343 1344 tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT; 1345 tcm->tcm_handle = cl->classid; 1346 if (cl->level == 0) 1347 tcm->tcm_info = cl->qdisc->handle; 1348 |
1349 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); | 1349 NLA_PUT(skb, TCA_OPTIONS, 0, NULL); |
1350 if (hfsc_dump_curves(skb, cl) < 0) | 1350 if (hfsc_dump_curves(skb, cl) < 0) |
1351 goto rtattr_failure; 1352 rta->rta_len = skb_tail_pointer(skb) - b; | 1351 goto nla_put_failure; 1352 nla->nla_len = skb_tail_pointer(skb) - b; |
1353 return skb->len; 1354 | 1353 return skb->len; 1354 |
1355 rtattr_failure: | 1355 nla_put_failure: |
1356 nlmsg_trim(skb, b); 1357 return -1; 1358} 1359 1360static int 1361hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg, 1362 struct gnet_dump *d) 1363{ --- 54 unchanged lines hidden (view full) --- 1418 if (next_time == 0 || next_time > q->root.cl_cfmin) 1419 next_time = q->root.cl_cfmin; 1420 } 1421 WARN_ON(next_time == 0); 1422 qdisc_watchdog_schedule(&q->watchdog, next_time); 1423} 1424 1425static int | 1356 nlmsg_trim(skb, b); 1357 return -1; 1358} 1359 1360static int 1361hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg, 1362 struct gnet_dump *d) 1363{ --- 54 unchanged lines hidden (view full) --- 1418 if (next_time == 0 || next_time > q->root.cl_cfmin) 1419 next_time = q->root.cl_cfmin; 1420 } 1421 WARN_ON(next_time == 0); 1422 qdisc_watchdog_schedule(&q->watchdog, next_time); 1423} 1424 1425static int |
1426hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt) | 1426hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) |
1427{ 1428 struct hfsc_sched *q = qdisc_priv(sch); 1429 struct tc_hfsc_qopt *qopt; 1430 unsigned int i; 1431 | 1427{ 1428 struct hfsc_sched *q = qdisc_priv(sch); 1429 struct tc_hfsc_qopt *qopt; 1430 unsigned int i; 1431 |
1432 if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt)) | 1432 if (opt == NULL || nla_len(opt) < sizeof(*qopt)) |
1433 return -EINVAL; | 1433 return -EINVAL; |
1434 qopt = RTA_DATA(opt); | 1434 qopt = nla_data(opt); |
1435 1436 q->defcls = qopt->defcls; 1437 for (i = 0; i < HFSC_HSIZE; i++) 1438 INIT_LIST_HEAD(&q->clhash[i]); 1439 q->eligible = RB_ROOT; 1440 INIT_LIST_HEAD(&q->droplist); 1441 skb_queue_head_init(&q->requeue); 1442 --- 11 unchanged lines hidden (view full) --- 1454 list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]); 1455 1456 qdisc_watchdog_init(&q->watchdog, sch); 1457 1458 return 0; 1459} 1460 1461static int | 1435 1436 q->defcls = qopt->defcls; 1437 for (i = 0; i < HFSC_HSIZE; i++) 1438 INIT_LIST_HEAD(&q->clhash[i]); 1439 q->eligible = RB_ROOT; 1440 INIT_LIST_HEAD(&q->droplist); 1441 skb_queue_head_init(&q->requeue); 1442 --- 11 unchanged lines hidden (view full) --- 1454 list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]); 1455 1456 qdisc_watchdog_init(&q->watchdog, sch); 1457 1458 return 0; 1459} 1460 1461static int |
1462hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt) | 1462hfsc_change_qdisc(struct Qdisc *sch, struct nlattr *opt) |
1463{ 1464 struct hfsc_sched *q = qdisc_priv(sch); 1465 struct tc_hfsc_qopt *qopt; 1466 | 1463{ 1464 struct hfsc_sched *q = qdisc_priv(sch); 1465 struct tc_hfsc_qopt *qopt; 1466 |
1467 if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt)) | 1467 if (opt == NULL || nla_len(opt) < sizeof(*qopt)) |
1468 return -EINVAL; | 1468 return -EINVAL; |
1469 qopt = RTA_DATA(opt); | 1469 qopt = nla_data(opt); |
1470 1471 sch_tree_lock(sch); 1472 q->defcls = qopt->defcls; 1473 sch_tree_unlock(sch); 1474 1475 return 0; 1476} 1477 --- 67 unchanged lines hidden (view full) --- 1545static int 1546hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) 1547{ 1548 struct hfsc_sched *q = qdisc_priv(sch); 1549 unsigned char *b = skb_tail_pointer(skb); 1550 struct tc_hfsc_qopt qopt; 1551 1552 qopt.defcls = q->defcls; | 1470 1471 sch_tree_lock(sch); 1472 q->defcls = qopt->defcls; 1473 sch_tree_unlock(sch); 1474 1475 return 0; 1476} 1477 --- 67 unchanged lines hidden (view full) --- 1545static int 1546hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) 1547{ 1548 struct hfsc_sched *q = qdisc_priv(sch); 1549 unsigned char *b = skb_tail_pointer(skb); 1550 struct tc_hfsc_qopt qopt; 1551 1552 qopt.defcls = q->defcls; |
1553 RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); | 1553 NLA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); |
1554 return skb->len; 1555 | 1554 return skb->len; 1555 |
1556 rtattr_failure: | 1556 nla_put_failure: |
1557 nlmsg_trim(skb, b); 1558 return -1; 1559} 1560 1561static int 1562hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 1563{ 1564 struct hfsc_class *cl; --- 183 unchanged lines hidden --- | 1557 nlmsg_trim(skb, b); 1558 return -1; 1559} 1560 1561static int 1562hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 1563{ 1564 struct hfsc_class *cl; --- 183 unchanged lines hidden --- |