From: Patrick McHardy <kaber@trash.net>
To: "David S. Miller" <davem@redhat.com>
Cc: netdev@oss.sgi.com, devik <devik@cdi.cz>, jamal <hadi@cyberus.ca>
Subject: [PATCH 2.6 3/4]: replace actlist by rbtrees
Date: Sat, 14 Aug 2004 22:00:41 +0200 [thread overview]
Message-ID: <411E6F69.4020102@trash.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 110 bytes --]
This patch replaces actlist by two rbtrees: vt_tree, sorted by virtual
time and cf_tree, sorted by fit-time.
[-- Attachment #2: 03-hfsc-2.6.diff --]
[-- Type: text/x-patch, Size: 9154 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/08/11 23:22:32+02:00 kaber@coreworks.de
# [NET_SCHED]: Replace actlist by rbtrees in HFSC scheduler
#
# Signed-off-by: Patrick McHardy <kaber@trash.net>
#
# net/sched/sch_hfsc.c
# 2004/08/11 23:22:08+02:00 kaber@coreworks.de +92 -90
# [NET_SCHED]: Replace actlist by rbtrees in HFSC scheduler
#
diff -Nru a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
--- a/net/sched/sch_hfsc.c 2004-08-12 23:25:39 +02:00
+++ b/net/sched/sch_hfsc.c 2004-08-12 23:25:39 +02:00
@@ -135,8 +135,10 @@
struct Qdisc *qdisc; /* leaf qdisc */
struct rb_node el_node; /* qdisc's eligible tree member */
- struct list_head actlist; /* active children list */
- struct list_head alist; /* active children list member */
+ struct rb_root vt_tree; /* active children sorted by cl_vt */
+ struct rb_node vt_node; /* parent's vt_tree member */
+ struct rb_root cf_tree; /* active children sorted by cl_f */
+ struct rb_node cf_node; /* parent's cf_heap member */
struct list_head hlist; /* hash list member */
struct list_head dlist; /* drop list member */
@@ -286,84 +288,51 @@
}
/*
- * active children list holds backlogged child classes being sorted
- * by their virtual time. each intermediate class has one active
- * children list.
+ * vttree holds holds backlogged child classes being sorted by their virtual
+ * time. each intermediate class has one vttree.
*/
static void
-actlist_insert(struct hfsc_class *cl)
+vttree_insert(struct hfsc_class *cl)
{
- struct list_head *head = &cl->cl_parent->actlist;
- struct hfsc_class *p;
-
- /* check the last entry first */
- if (list_empty(head) ||
- ((p = list_entry(head->prev, struct hfsc_class, alist)) &&
- p->cl_vt <= cl->cl_vt)) {
- list_add_tail(&cl->alist, head);
- return;
- }
+ struct rb_node **p = &cl->cl_parent->vt_tree.rb_node;
+ struct rb_node *parent = NULL;
+ struct hfsc_class *cl1;
- list_for_each_entry(p, head, alist) {
- if (cl->cl_vt < p->cl_vt) {
- /* insert cl before p */
- list_add_tail(&cl->alist, &p->alist);
- return;
- }
+ while (*p != NULL) {
+ parent = *p;
+ cl1 = rb_entry(parent, struct hfsc_class, vt_node);
+ if (cl->cl_vt >= cl1->cl_vt)
+ p = &parent->rb_right;
+ else
+ p = &parent->rb_left;
}
- ASSERT(0); /* should not reach here */
+ rb_link_node(&cl->vt_node, parent, p);
+ rb_insert_color(&cl->vt_node, &cl->cl_parent->vt_tree);
}
static inline void
-actlist_remove(struct hfsc_class *cl)
+vttree_remove(struct hfsc_class *cl)
{
- list_del(&cl->alist);
+ rb_erase(&cl->vt_node, &cl->cl_parent->vt_tree);
}
-static void
-actlist_update(struct hfsc_class *cl)
+static inline void
+vttree_update(struct hfsc_class *cl)
{
- struct list_head *head = &cl->cl_parent->actlist;
- struct hfsc_class *p, *last;
-
- /*
- * the virtual time of a class increases monotonically.
- * if the next entry has a larger virtual time, nothing to do.
- */
- if (cl->alist.next == head ||
- ((p = list_entry(cl->alist.next, struct hfsc_class, alist)) &&
- cl->cl_vt <= p->cl_vt))
- return;
-
- /* check the last entry */
- last = list_entry(head->prev, struct hfsc_class, alist);
- if (last->cl_vt <= cl->cl_vt) {
- list_move_tail(&cl->alist, head);
- return;
- }
-
- /*
- * the new position must be between the next entry
- * and the last entry
- */
- list_for_each_entry_continue(p, head, alist) {
- if (cl->cl_vt < p->cl_vt) {
- list_move_tail(&cl->alist, &p->alist);
- return;
- }
- }
- ASSERT(0); /* should not reach here */
+ vttree_remove(cl);
+ vttree_insert(cl);
}
static inline struct hfsc_class *
-actlist_firstfit(struct hfsc_class *cl, u64 cur_time)
+vttree_firstfit(struct hfsc_class *cl, u64 cur_time)
{
struct hfsc_class *p;
+ struct rb_node *n;
- list_for_each_entry(p, &cl->actlist, alist) {
- if (p->cl_f <= cur_time) {
+ for (n = rb_first(&cl->vt_tree); n != NULL; n = rb_next(n)) {
+ p = rb_entry(n, struct hfsc_class, vt_node);
+ if (p->cl_f <= cur_time)
return p;
- }
}
return NULL;
}
@@ -372,14 +341,14 @@
* get the leaf class with the minimum vt in the hierarchy
*/
static struct hfsc_class *
-actlist_get_minvt(struct hfsc_class *cl, u64 cur_time)
+vttree_get_minvt(struct hfsc_class *cl, u64 cur_time)
{
/* if root-class's cfmin is bigger than cur_time nothing to do */
if (cl->cl_cfmin > cur_time)
return NULL;
while (cl->level > 0) {
- cl = actlist_firstfit(cl, cur_time);
+ cl = vttree_firstfit(cl, cur_time);
if (cl == NULL)
return NULL;
/*
@@ -391,6 +360,38 @@
return cl;
}
+static void
+cftree_insert(struct hfsc_class *cl)
+{
+ struct rb_node **p = &cl->cl_parent->cf_tree.rb_node;
+ struct rb_node *parent = NULL;
+ struct hfsc_class *cl1;
+
+ while (*p != NULL) {
+ parent = *p;
+ cl1 = rb_entry(parent, struct hfsc_class, cf_node);
+ if (cl->cl_f >= cl1->cl_f)
+ p = &parent->rb_right;
+ else
+ p = &parent->rb_left;
+ }
+ rb_link_node(&cl->cf_node, parent, p);
+ rb_insert_color(&cl->cf_node, &cl->cl_parent->cf_tree);
+}
+
+static inline void
+cftree_remove(struct hfsc_class *cl)
+{
+ rb_erase(&cl->cf_node, &cl->cl_parent->cf_tree);
+}
+
+static inline void
+cftree_update(struct hfsc_class *cl)
+{
+ cftree_remove(cl);
+ cftree_insert(cl);
+}
+
/*
* service curve support functions
*
@@ -702,32 +703,25 @@
cl->cl_d = rtsc_y2x(&cl->cl_deadline, cl->cl_cumul + next_len);
}
-static void
+static inline void
update_cfmin(struct hfsc_class *cl)
{
+ struct rb_node *n = rb_first(&cl->cf_tree);
struct hfsc_class *p;
- u64 cfmin;
- if (list_empty(&cl->actlist)) {
+ if (n == NULL) {
cl->cl_cfmin = 0;
return;
}
- cfmin = HT_INFINITY;
- list_for_each_entry(p, &cl->actlist, alist) {
- if (p->cl_f == 0) {
- cl->cl_cfmin = 0;
- return;
- }
- if (p->cl_f < cfmin)
- cfmin = p->cl_f;
- }
- cl->cl_cfmin = cfmin;
+ p = rb_entry(n, struct hfsc_class, cf_node);
+ cl->cl_cfmin = p->cl_f;
}
static void
init_vf(struct hfsc_class *cl, unsigned int len)
{
struct hfsc_class *max_cl, *p;
+ struct rb_node *n;
u64 vt, f, cur_time;
int go_active;
@@ -740,9 +734,9 @@
go_active = 0;
if (go_active) {
- if (!list_empty(&cl->cl_parent->actlist)) {
- max_cl = list_entry(cl->cl_parent->actlist.prev,
- struct hfsc_class, alist);
+ n = rb_last(&cl->cl_parent->vt_tree);
+ if (n != NULL) {
+ max_cl = rb_entry(n, struct hfsc_class,vt_node);
/*
* set vt to the average of the min and max
* classes. if the parent's period didn't
@@ -787,7 +781,8 @@
cl->cl_parentperiod++;
cl->cl_f = 0;
- actlist_insert(cl);
+ vttree_insert(cl);
+ cftree_insert(cl);
if (cl->cl_flags & HFSC_USC) {
/* class has upper limit curve */
@@ -807,6 +802,7 @@
f = max(cl->cl_myf, cl->cl_cfmin);
if (f != cl->cl_f) {
cl->cl_f = f;
+ cftree_update(cl);
update_cfmin(cl->cl_parent);
}
}
@@ -839,9 +835,10 @@
if (cl->cl_vt > cl->cl_parent->cl_cvtmax)
cl->cl_parent->cl_cvtmax = cl->cl_vt;
- /* remove this class from the vt list */
- actlist_remove(cl);
+ /* remove this class from the vt tree */
+ vttree_remove(cl);
+ cftree_remove(cl);
update_cfmin(cl->cl_parent);
continue;
@@ -863,8 +860,8 @@
cl->cl_vt = cl->cl_parent->cl_cvtmin;
}
- /* update the vt list */
- actlist_update(cl);
+ /* update the vt tree */
+ vttree_update(cl);
if (cl->cl_flags & HFSC_USC) {
cl->cl_myf = cl->cl_myfadj + rtsc_y2x(&cl->cl_ulimit,
@@ -894,6 +891,7 @@
f = max(cl->cl_myf, cl->cl_cfmin);
if (f != cl->cl_f) {
cl->cl_f = f;
+ cftree_update(cl);
update_cfmin(cl->cl_parent);
}
}
@@ -919,8 +917,8 @@
list_del(&cl->dlist);
/*
- * actlist is now handled in update_vf() so that update_vf(cl, 0, 0)
- * needs to be called explicitly to remove a class from actlist
+ * vttree is now handled in update_vf() so that update_vf(cl, 0, 0)
+ * needs to be called explicitly to remove a class from vttree.
*/
}
@@ -1144,7 +1142,8 @@
cl->qdisc = &noop_qdisc;
cl->stats_lock = &sch->dev->queue_lock;
INIT_LIST_HEAD(&cl->children);
- INIT_LIST_HEAD(&cl->actlist);
+ cl->vt_tree = RB_ROOT;
+ cl->cf_tree = RB_ROOT;
sch_tree_lock(sch);
list_add_tail(&cl->hlist, &q->clhash[hfsc_hash(classid)]);
@@ -1544,7 +1543,8 @@
q->root.qdisc = &noop_qdisc;
q->root.stats_lock = &sch->dev->queue_lock;
INIT_LIST_HEAD(&q->root.children);
- INIT_LIST_HEAD(&q->root.actlist);
+ q->root.vt_tree = RB_ROOT;
+ q->root.cf_tree = RB_ROOT;
list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]);
@@ -1591,7 +1591,9 @@
cl->cl_myfadj = 0;
cl->cl_cfmin = 0;
cl->cl_nactive = 0;
- INIT_LIST_HEAD(&cl->actlist);
+
+ cl->vt_tree = RB_ROOT;
+ cl->cf_tree = RB_ROOT;
qdisc_reset(cl->qdisc);
if (cl->cl_flags & HFSC_RSC)
@@ -1729,7 +1731,7 @@
* use link-sharing criteria
* get the class with the minimum vt in the hierarchy
*/
- cl = actlist_get_minvt(&q->root, cur_time);
+ cl = vttree_get_minvt(&q->root, cur_time);
if (cl == NULL) {
sch->stats.overlimits++;
hfsc_schedule_watchdog(sch, cur_time);
reply other threads:[~2004-08-14 20:00 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=411E6F69.4020102@trash.net \
--to=kaber@trash.net \
--cc=davem@redhat.com \
--cc=devik@cdi.cz \
--cc=hadi@cyberus.ca \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).