diff options
-rw-r--r-- | net/sched/sch_htb.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index e7461a17d71e..128a5ab2e376 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -81,9 +81,8 @@ struct htb_class { | |||
81 | 81 | ||
82 | /* topology */ | 82 | /* topology */ |
83 | int level; /* our level (see above) */ | 83 | int level; /* our level (see above) */ |
84 | unsigned int children; | ||
84 | struct htb_class *parent; /* parent class */ | 85 | struct htb_class *parent; /* parent class */ |
85 | struct list_head sibling; /* sibling list item */ | ||
86 | struct list_head children; /* children list */ | ||
87 | 86 | ||
88 | union { | 87 | union { |
89 | struct htb_class_leaf { | 88 | struct htb_class_leaf { |
@@ -138,7 +137,6 @@ static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate, | |||
138 | } | 137 | } |
139 | 138 | ||
140 | struct htb_sched { | 139 | struct htb_sched { |
141 | struct list_head root; /* root classes list */ | ||
142 | struct Qdisc_class_hash clhash; | 140 | struct Qdisc_class_hash clhash; |
143 | struct list_head drops[TC_HTB_NUMPRIO];/* active leaves (for drops) */ | 141 | struct list_head drops[TC_HTB_NUMPRIO];/* active leaves (for drops) */ |
144 | 142 | ||
@@ -1020,7 +1018,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1020 | return -EINVAL; | 1018 | return -EINVAL; |
1021 | } | 1019 | } |
1022 | 1020 | ||
1023 | INIT_LIST_HEAD(&q->root); | ||
1024 | err = qdisc_class_hash_init(&q->clhash); | 1021 | err = qdisc_class_hash_init(&q->clhash); |
1025 | if (err < 0) | 1022 | if (err < 0) |
1026 | return err; | 1023 | return err; |
@@ -1175,12 +1172,9 @@ static inline int htb_parent_last_child(struct htb_class *cl) | |||
1175 | if (!cl->parent) | 1172 | if (!cl->parent) |
1176 | /* the root class */ | 1173 | /* the root class */ |
1177 | return 0; | 1174 | return 0; |
1178 | 1175 | if (cl->parent->children > 1) | |
1179 | if (!(cl->parent->children.next == &cl->sibling && | ||
1180 | cl->parent->children.prev == &cl->sibling)) | ||
1181 | /* not the last child */ | 1176 | /* not the last child */ |
1182 | return 0; | 1177 | return 0; |
1183 | |||
1184 | return 1; | 1178 | return 1; |
1185 | } | 1179 | } |
1186 | 1180 | ||
@@ -1259,7 +1253,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) | |||
1259 | // TODO: why don't allow to delete subtree ? references ? does | 1253 | // TODO: why don't allow to delete subtree ? references ? does |
1260 | // tc subsys quarantee us that in htb_destroy it holds no class | 1254 | // tc subsys quarantee us that in htb_destroy it holds no class |
1261 | // refs so that we can remove children safely there ? | 1255 | // refs so that we can remove children safely there ? |
1262 | if (!list_empty(&cl->children) || cl->filter_cnt) | 1256 | if (cl->children || cl->filter_cnt) |
1263 | return -EBUSY; | 1257 | return -EBUSY; |
1264 | 1258 | ||
1265 | if (!cl->level && htb_parent_last_child(cl)) { | 1259 | if (!cl->level && htb_parent_last_child(cl)) { |
@@ -1278,7 +1272,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) | |||
1278 | 1272 | ||
1279 | /* delete from hash and active; remainder in destroy_class */ | 1273 | /* delete from hash and active; remainder in destroy_class */ |
1280 | qdisc_class_hash_remove(&q->clhash, &cl->common); | 1274 | qdisc_class_hash_remove(&q->clhash, &cl->common); |
1281 | list_del(&cl->sibling); | 1275 | cl->parent->children--; |
1282 | 1276 | ||
1283 | if (cl->prio_activity) | 1277 | if (cl->prio_activity) |
1284 | htb_deactivate(q, cl); | 1278 | htb_deactivate(q, cl); |
@@ -1373,8 +1367,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1373 | &sch->dev->queue_lock, | 1367 | &sch->dev->queue_lock, |
1374 | tca[TCA_RATE] ? : &est.nla); | 1368 | tca[TCA_RATE] ? : &est.nla); |
1375 | cl->refcnt = 1; | 1369 | cl->refcnt = 1; |
1376 | INIT_LIST_HEAD(&cl->sibling); | 1370 | cl->children = 0; |
1377 | INIT_LIST_HEAD(&cl->children); | ||
1378 | INIT_LIST_HEAD(&cl->un.leaf.drop_list); | 1371 | INIT_LIST_HEAD(&cl->un.leaf.drop_list); |
1379 | RB_CLEAR_NODE(&cl->pq_node); | 1372 | RB_CLEAR_NODE(&cl->pq_node); |
1380 | 1373 | ||
@@ -1420,8 +1413,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1420 | 1413 | ||
1421 | /* attach to the hash list and parent's family */ | 1414 | /* attach to the hash list and parent's family */ |
1422 | qdisc_class_hash_insert(&q->clhash, &cl->common); | 1415 | qdisc_class_hash_insert(&q->clhash, &cl->common); |
1423 | list_add_tail(&cl->sibling, | 1416 | if (parent) |
1424 | parent ? &parent->children : &q->root); | 1417 | parent->children++; |
1425 | } else { | 1418 | } else { |
1426 | if (tca[TCA_RATE]) | 1419 | if (tca[TCA_RATE]) |
1427 | gen_replace_estimator(&cl->bstats, &cl->rate_est, | 1420 | gen_replace_estimator(&cl->bstats, &cl->rate_est, |