aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/sch_htb.c21
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
140struct htb_sched { 139struct 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,