sch_hfsc.c (14f0290ba44de6ed435fea24bba26e7868421c66) | sch_hfsc.c (cc7ec456f82da7f89a5b376e613b3ac4311b3e9a) |
---|---|
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 * --- 67 unchanged lines hidden (view full) --- 76 * 77 * The service curve parameters are converted to the internal 78 * representation. The slope values are scaled to avoid overflow. 79 * the inverse slope values as well as the y-projection of the 1st 80 * segment are kept in order to avoid 64-bit divide operations 81 * that are expensive on 32-bit architectures. 82 */ 83 | 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 * --- 67 unchanged lines hidden (view full) --- 76 * 77 * The service curve parameters are converted to the internal 78 * representation. The slope values are scaled to avoid overflow. 79 * the inverse slope values as well as the y-projection of the 1st 80 * segment are kept in order to avoid 64-bit divide operations 81 * that are expensive on 32-bit architectures. 82 */ 83 |
84struct internal_sc 85{ | 84struct internal_sc { |
86 u64 sm1; /* scaled slope of the 1st segment */ 87 u64 ism1; /* scaled inverse-slope of the 1st segment */ 88 u64 dx; /* the x-projection of the 1st segment */ 89 u64 dy; /* the y-projection of the 1st segment */ 90 u64 sm2; /* scaled slope of the 2nd segment */ 91 u64 ism2; /* scaled inverse-slope of the 2nd segment */ 92}; 93 94/* runtime service curve */ | 85 u64 sm1; /* scaled slope of the 1st segment */ 86 u64 ism1; /* scaled inverse-slope of the 1st segment */ 87 u64 dx; /* the x-projection of the 1st segment */ 88 u64 dy; /* the y-projection of the 1st segment */ 89 u64 sm2; /* scaled slope of the 2nd segment */ 90 u64 ism2; /* scaled inverse-slope of the 2nd segment */ 91}; 92 93/* runtime service curve */ |
95struct runtime_sc 96{ | 94struct runtime_sc { |
97 u64 x; /* current starting position on x-axis */ 98 u64 y; /* current starting position on y-axis */ 99 u64 sm1; /* scaled slope of the 1st segment */ 100 u64 ism1; /* scaled inverse-slope of the 1st segment */ 101 u64 dx; /* the x-projection of the 1st segment */ 102 u64 dy; /* the y-projection of the 1st segment */ 103 u64 sm2; /* scaled slope of the 2nd segment */ 104 u64 ism2; /* scaled inverse-slope of the 2nd segment */ 105}; 106 | 95 u64 x; /* current starting position on x-axis */ 96 u64 y; /* current starting position on y-axis */ 97 u64 sm1; /* scaled slope of the 1st segment */ 98 u64 ism1; /* scaled inverse-slope of the 1st segment */ 99 u64 dx; /* the x-projection of the 1st segment */ 100 u64 dy; /* the y-projection of the 1st segment */ 101 u64 sm2; /* scaled slope of the 2nd segment */ 102 u64 ism2; /* scaled inverse-slope of the 2nd segment */ 103}; 104 |
107enum hfsc_class_flags 108{ | 105enum hfsc_class_flags { |
109 HFSC_RSC = 0x1, 110 HFSC_FSC = 0x2, 111 HFSC_USC = 0x4 112}; 113 | 106 HFSC_RSC = 0x1, 107 HFSC_FSC = 0x2, 108 HFSC_USC = 0x4 109}; 110 |
114struct hfsc_class 115{ | 111struct hfsc_class { |
116 struct Qdisc_class_common cl_common; 117 unsigned int refcnt; /* usage count */ 118 119 struct gnet_stats_basic_packed bstats; 120 struct gnet_stats_queue qstats; 121 struct gnet_stats_rate_est rate_est; 122 unsigned int level; /* class level in hierarchy */ 123 struct tcf_proto *filter_list; /* filter list */ --- 11 unchanged lines hidden (view full) --- 135 struct rb_root cf_tree; /* active children sorted by cl_f */ 136 struct rb_node cf_node; /* parent's cf_heap member */ 137 struct list_head dlist; /* drop list member */ 138 139 u64 cl_total; /* total work in bytes */ 140 u64 cl_cumul; /* cumulative work in bytes done by 141 real-time criteria */ 142 | 112 struct Qdisc_class_common cl_common; 113 unsigned int refcnt; /* usage count */ 114 115 struct gnet_stats_basic_packed bstats; 116 struct gnet_stats_queue qstats; 117 struct gnet_stats_rate_est rate_est; 118 unsigned int level; /* class level in hierarchy */ 119 struct tcf_proto *filter_list; /* filter list */ --- 11 unchanged lines hidden (view full) --- 131 struct rb_root cf_tree; /* active children sorted by cl_f */ 132 struct rb_node cf_node; /* parent's cf_heap member */ 133 struct list_head dlist; /* drop list member */ 134 135 u64 cl_total; /* total work in bytes */ 136 u64 cl_cumul; /* cumulative work in bytes done by 137 real-time criteria */ 138 |
143 u64 cl_d; /* deadline*/ 144 u64 cl_e; /* eligible time */ | 139 u64 cl_d; /* deadline*/ 140 u64 cl_e; /* eligible time */ |
145 u64 cl_vt; /* virtual time */ 146 u64 cl_f; /* time when this class will fit for 147 link-sharing, max(myf, cfmin) */ 148 u64 cl_myf; /* my fit-time (calculated from this 149 class's own upperlimit curve) */ 150 u64 cl_myfadj; /* my fit-time adjustment (to cancel 151 history dependence) */ 152 u64 cl_cfmin; /* earliest children's fit-time (used --- 18 unchanged lines hidden (view full) --- 171 struct runtime_sc cl_ulimit; /* upperlimit curve */ 172 173 unsigned long cl_flags; /* which curves are valid */ 174 unsigned long cl_vtperiod; /* vt period sequence number */ 175 unsigned long cl_parentperiod;/* parent's vt period sequence number*/ 176 unsigned long cl_nactive; /* number of active children */ 177}; 178 | 141 u64 cl_vt; /* virtual time */ 142 u64 cl_f; /* time when this class will fit for 143 link-sharing, max(myf, cfmin) */ 144 u64 cl_myf; /* my fit-time (calculated from this 145 class's own upperlimit curve) */ 146 u64 cl_myfadj; /* my fit-time adjustment (to cancel 147 history dependence) */ 148 u64 cl_cfmin; /* earliest children's fit-time (used --- 18 unchanged lines hidden (view full) --- 167 struct runtime_sc cl_ulimit; /* upperlimit curve */ 168 169 unsigned long cl_flags; /* which curves are valid */ 170 unsigned long cl_vtperiod; /* vt period sequence number */ 171 unsigned long cl_parentperiod;/* parent's vt period sequence number*/ 172 unsigned long cl_nactive; /* number of active children */ 173}; 174 |
179struct hfsc_sched 180{ | 175struct hfsc_sched { |
181 u16 defcls; /* default class id */ 182 struct hfsc_class root; /* root class */ 183 struct Qdisc_class_hash clhash; /* class hash */ 184 struct rb_root eligible; /* eligible tree */ 185 struct list_head droplist; /* active leaf class list (for 186 dropping) */ 187 struct qdisc_watchdog watchdog; /* watchdog timer */ 188}; --- 499 unchanged lines hidden (view full) --- 688 if (go_active && cl->cl_nactive++ == 0) 689 go_active = 1; 690 else 691 go_active = 0; 692 693 if (go_active) { 694 n = rb_last(&cl->cl_parent->vt_tree); 695 if (n != NULL) { | 176 u16 defcls; /* default class id */ 177 struct hfsc_class root; /* root class */ 178 struct Qdisc_class_hash clhash; /* class hash */ 179 struct rb_root eligible; /* eligible tree */ 180 struct list_head droplist; /* active leaf class list (for 181 dropping) */ 182 struct qdisc_watchdog watchdog; /* watchdog timer */ 183}; --- 499 unchanged lines hidden (view full) --- 683 if (go_active && cl->cl_nactive++ == 0) 684 go_active = 1; 685 else 686 go_active = 0; 687 688 if (go_active) { 689 n = rb_last(&cl->cl_parent->vt_tree); 690 if (n != NULL) { |
696 max_cl = rb_entry(n, struct hfsc_class,vt_node); | 691 max_cl = rb_entry(n, struct hfsc_class, vt_node); |
697 /* 698 * set vt to the average of the min and max 699 * classes. if the parent's period didn't 700 * change, don't decrease vt of the class. 701 */ 702 vt = max_cl->cl_vt; 703 if (cl->cl_parent->cl_cvtmin != 0) 704 vt = (cl->cl_parent->cl_cvtmin + vt)/2; --- 467 unchanged lines hidden (view full) --- 1172 switch (result) { 1173 case TC_ACT_QUEUED: 1174 case TC_ACT_STOLEN: 1175 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; 1176 case TC_ACT_SHOT: 1177 return NULL; 1178 } 1179#endif | 692 /* 693 * set vt to the average of the min and max 694 * classes. if the parent's period didn't 695 * change, don't decrease vt of the class. 696 */ 697 vt = max_cl->cl_vt; 698 if (cl->cl_parent->cl_cvtmin != 0) 699 vt = (cl->cl_parent->cl_cvtmin + vt)/2; --- 467 unchanged lines hidden (view full) --- 1167 switch (result) { 1168 case TC_ACT_QUEUED: 1169 case TC_ACT_STOLEN: 1170 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; 1171 case TC_ACT_SHOT: 1172 return NULL; 1173 } 1174#endif |
1180 if ((cl = (struct hfsc_class *)res.class) == NULL) { 1181 if ((cl = hfsc_find_class(res.classid, sch)) == NULL) | 1175 cl = (struct hfsc_class *)res.class; 1176 if (!cl) { 1177 cl = hfsc_find_class(res.classid, sch); 1178 if (!cl) |
1182 break; /* filter selected invalid classid */ 1183 if (cl->level >= head->level) 1184 break; /* filter may only point downwards */ 1185 } 1186 1187 if (cl->level == 0) 1188 return cl; /* hit leaf class */ 1189 --- 121 unchanged lines hidden (view full) --- 1311 NLA_PUT(skb, attr, sizeof(tsc), &tsc); 1312 1313 return skb->len; 1314 1315 nla_put_failure: 1316 return -1; 1317} 1318 | 1179 break; /* filter selected invalid classid */ 1180 if (cl->level >= head->level) 1181 break; /* filter may only point downwards */ 1182 } 1183 1184 if (cl->level == 0) 1185 return cl; /* hit leaf class */ 1186 --- 121 unchanged lines hidden (view full) --- 1308 NLA_PUT(skb, attr, sizeof(tsc), &tsc); 1309 1310 return skb->len; 1311 1312 nla_put_failure: 1313 return -1; 1314} 1315 |
1319static inline int | 1316static int |
1320hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl) 1321{ 1322 if ((cl->cl_flags & HFSC_RSC) && 1323 (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0)) 1324 goto nla_put_failure; 1325 1326 if ((cl->cl_flags & HFSC_FSC) && 1327 (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0)) --- 87 unchanged lines hidden (view full) --- 1415 1416static void 1417hfsc_schedule_watchdog(struct Qdisc *sch) 1418{ 1419 struct hfsc_sched *q = qdisc_priv(sch); 1420 struct hfsc_class *cl; 1421 u64 next_time = 0; 1422 | 1317hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl) 1318{ 1319 if ((cl->cl_flags & HFSC_RSC) && 1320 (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0)) 1321 goto nla_put_failure; 1322 1323 if ((cl->cl_flags & HFSC_FSC) && 1324 (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0)) --- 87 unchanged lines hidden (view full) --- 1412 1413static void 1414hfsc_schedule_watchdog(struct Qdisc *sch) 1415{ 1416 struct hfsc_sched *q = qdisc_priv(sch); 1417 struct hfsc_class *cl; 1418 u64 next_time = 0; 1419 |
1423 if ((cl = eltree_get_minel(q)) != NULL) | 1420 cl = eltree_get_minel(q); 1421 if (cl) |
1424 next_time = cl->cl_e; 1425 if (q->root.cl_cfmin != 0) { 1426 if (next_time == 0 || next_time > q->root.cl_cfmin) 1427 next_time = q->root.cl_cfmin; 1428 } 1429 WARN_ON(next_time == 0); 1430 qdisc_watchdog_schedule(&q->watchdog, next_time); 1431} --- 189 unchanged lines hidden (view full) --- 1621 1622 cur_time = psched_get_time(); 1623 1624 /* 1625 * if there are eligible classes, use real-time criteria. 1626 * find the class with the minimum deadline among 1627 * the eligible classes. 1628 */ | 1422 next_time = cl->cl_e; 1423 if (q->root.cl_cfmin != 0) { 1424 if (next_time == 0 || next_time > q->root.cl_cfmin) 1425 next_time = q->root.cl_cfmin; 1426 } 1427 WARN_ON(next_time == 0); 1428 qdisc_watchdog_schedule(&q->watchdog, next_time); 1429} --- 189 unchanged lines hidden (view full) --- 1619 1620 cur_time = psched_get_time(); 1621 1622 /* 1623 * if there are eligible classes, use real-time criteria. 1624 * find the class with the minimum deadline among 1625 * the eligible classes. 1626 */ |
1629 if ((cl = eltree_get_mindl(q, cur_time)) != NULL) { | 1627 cl = eltree_get_mindl(q, cur_time); 1628 if (cl) { |
1630 realtime = 1; 1631 } else { 1632 /* 1633 * use link-sharing criteria 1634 * get the class with the minimum vt in the hierarchy 1635 */ 1636 cl = vttree_get_minvt(&q->root, cur_time); 1637 if (cl == NULL) { --- 108 unchanged lines hidden --- | 1629 realtime = 1; 1630 } else { 1631 /* 1632 * use link-sharing criteria 1633 * get the class with the minimum vt in the hierarchy 1634 */ 1635 cl = vttree_get_minvt(&q->root, cur_time); 1636 if (cl == NULL) { --- 108 unchanged lines hidden --- |