Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
c10c32d3
Commit
c10c32d3
authored
Aug 09, 2004
by
Martin Devera
Committed by
Stephen Hemminger
Aug 09, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PKT_SCHED]: Fix borrowing fairness in htb.
parent
54ab147e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
8 deletions
+55
-8
net/sched/sch_htb.c
net/sched/sch_htb.c
+55
-8
No files found.
net/sched/sch_htb.c
View file @
c10c32d3
...
@@ -76,7 +76,7 @@
...
@@ -76,7 +76,7 @@
#define HTB_HYSTERESIS 1
/* whether to use mode hysteresis for speedup */
#define HTB_HYSTERESIS 1
/* whether to use mode hysteresis for speedup */
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
#define HTB_VER 0x3001
0
/* major must be matched with number suplied by TC as version */
#define HTB_VER 0x3001
1
/* major must be matched with number suplied by TC as version */
#if HTB_VER >> 16 != TC_HTB_PROTOVER
#if HTB_VER >> 16 != TC_HTB_PROTOVER
#error "Mismatched sch_htb.c and pkt_sch.h"
#error "Mismatched sch_htb.c and pkt_sch.h"
...
@@ -172,6 +172,11 @@ struct htb_class
...
@@ -172,6 +172,11 @@ struct htb_class
struct
htb_class_inner
{
struct
htb_class_inner
{
struct
rb_root
feed
[
TC_HTB_NUMPRIO
];
/* feed trees */
struct
rb_root
feed
[
TC_HTB_NUMPRIO
];
/* feed trees */
struct
rb_node
*
ptr
[
TC_HTB_NUMPRIO
];
/* current class ptr */
struct
rb_node
*
ptr
[
TC_HTB_NUMPRIO
];
/* current class ptr */
/* When class changes from state 1->2 and disconnects from
parent's feed then we lost ptr value and start from the
first child again. Here we store classid of the
last valid ptr (used when ptr is NULL). */
u32
last_ptr_id
[
TC_HTB_NUMPRIO
];
}
inner
;
}
inner
;
}
un
;
}
un
;
struct
rb_node
node
[
TC_HTB_NUMPRIO
];
/* node for self or feed tree */
struct
rb_node
node
[
TC_HTB_NUMPRIO
];
/* node for self or feed tree */
...
@@ -218,6 +223,7 @@ struct htb_sched
...
@@ -218,6 +223,7 @@ struct htb_sched
struct
rb_root
row
[
TC_HTB_MAXDEPTH
][
TC_HTB_NUMPRIO
];
struct
rb_root
row
[
TC_HTB_MAXDEPTH
][
TC_HTB_NUMPRIO
];
int
row_mask
[
TC_HTB_MAXDEPTH
];
int
row_mask
[
TC_HTB_MAXDEPTH
];
struct
rb_node
*
ptr
[
TC_HTB_MAXDEPTH
][
TC_HTB_NUMPRIO
];
struct
rb_node
*
ptr
[
TC_HTB_MAXDEPTH
][
TC_HTB_NUMPRIO
];
u32
last_ptr_id
[
TC_HTB_MAXDEPTH
][
TC_HTB_NUMPRIO
];
/* self wait list - roots of wait PQs per row */
/* self wait list - roots of wait PQs per row */
struct
rb_root
wait_pq
[
TC_HTB_MAXDEPTH
];
struct
rb_root
wait_pq
[
TC_HTB_MAXDEPTH
];
...
@@ -592,8 +598,13 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl)
...
@@ -592,8 +598,13 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl)
int
prio
=
ffz
(
~
m
);
int
prio
=
ffz
(
~
m
);
m
&=
~
(
1
<<
prio
);
m
&=
~
(
1
<<
prio
);
if
(
p
->
un
.
inner
.
ptr
[
prio
]
==
cl
->
node
+
prio
)
if
(
p
->
un
.
inner
.
ptr
[
prio
]
==
cl
->
node
+
prio
)
{
htb_next_rb_node
(
p
->
un
.
inner
.
ptr
+
prio
);
/* we are removing child which is pointed to from
parent feed - forget the pointer but remember
classid */
p
->
un
.
inner
.
last_ptr_id
[
prio
]
=
cl
->
classid
;
p
->
un
.
inner
.
ptr
[
prio
]
=
NULL
;
}
htb_safe_rb_erase
(
cl
->
node
+
prio
,
p
->
un
.
inner
.
feed
+
prio
);
htb_safe_rb_erase
(
cl
->
node
+
prio
,
p
->
un
.
inner
.
feed
+
prio
);
...
@@ -952,25 +963,56 @@ static long htb_do_events(struct htb_sched *q,int level)
...
@@ -952,25 +963,56 @@ static long htb_do_events(struct htb_sched *q,int level)
return
HZ
/
10
;
return
HZ
/
10
;
}
}
/* Returns class->node+prio from id-tree where classe's id is >= id. NULL
is no such one exists. */
static
struct
rb_node
*
htb_id_find_next_upper
(
int
prio
,
struct
rb_node
*
n
,
u32
id
)
{
struct
rb_node
*
r
=
NULL
;
while
(
n
)
{
struct
htb_class
*
cl
=
rb_entry
(
n
,
struct
htb_class
,
node
[
prio
]);
if
(
id
==
cl
->
classid
)
return
n
;
if
(
id
>
cl
->
classid
)
{
n
=
n
->
rb_right
;
}
else
{
r
=
n
;
n
=
n
->
rb_left
;
}
}
return
r
;
}
/**
/**
* htb_lookup_leaf - returns next leaf class in DRR order
* htb_lookup_leaf - returns next leaf class in DRR order
*
*
* Find leaf where current feed pointers points to.
* Find leaf where current feed pointers points to.
*/
*/
static
struct
htb_class
*
static
struct
htb_class
*
htb_lookup_leaf
(
struct
rb_root
*
tree
,
int
prio
,
struct
rb_node
**
pptr
)
htb_lookup_leaf
(
HTB_ARGQ
struct
rb_root
*
tree
,
int
prio
,
struct
rb_node
**
pptr
,
u32
*
pid
)
{
{
int
i
;
int
i
;
struct
{
struct
{
struct
rb_node
*
root
;
struct
rb_node
*
root
;
struct
rb_node
**
pptr
;
struct
rb_node
**
pptr
;
u32
*
pid
;
}
stk
[
TC_HTB_MAXDEPTH
],
*
sp
=
stk
;
}
stk
[
TC_HTB_MAXDEPTH
],
*
sp
=
stk
;
BUG_TRAP
(
tree
->
rb_node
);
BUG_TRAP
(
tree
->
rb_node
);
sp
->
root
=
tree
->
rb_node
;
sp
->
root
=
tree
->
rb_node
;
sp
->
pptr
=
pptr
;
sp
->
pptr
=
pptr
;
sp
->
pid
=
pid
;
for
(
i
=
0
;
i
<
65535
;
i
++
)
{
for
(
i
=
0
;
i
<
65535
;
i
++
)
{
HTB_DBG
(
4
,
2
,
"htb_lleaf ptr=%p pid=%X
\n
"
,
*
sp
->
pptr
,
*
sp
->
pid
);
if
(
!*
sp
->
pptr
&&
*
sp
->
pid
)
{
/* ptr was invalidated but id is valid - try to recover
the original or next ptr */
*
sp
->
pptr
=
htb_id_find_next_upper
(
prio
,
sp
->
root
,
*
sp
->
pid
);
}
*
sp
->
pid
=
0
;
/* ptr is valid now so that remove this hint as it
can become out of date quickly */
if
(
!*
sp
->
pptr
)
{
/* we are at right end; rewind & go up */
if
(
!*
sp
->
pptr
)
{
/* we are at right end; rewind & go up */
*
sp
->
pptr
=
sp
->
root
;
*
sp
->
pptr
=
sp
->
root
;
while
((
*
sp
->
pptr
)
->
rb_left
)
while
((
*
sp
->
pptr
)
->
rb_left
)
...
@@ -988,6 +1030,7 @@ htb_lookup_leaf(struct rb_root *tree,int prio,struct rb_node **pptr)
...
@@ -988,6 +1030,7 @@ htb_lookup_leaf(struct rb_root *tree,int prio,struct rb_node **pptr)
return
cl
;
return
cl
;
(
++
sp
)
->
root
=
cl
->
un
.
inner
.
feed
[
prio
].
rb_node
;
(
++
sp
)
->
root
=
cl
->
un
.
inner
.
feed
[
prio
].
rb_node
;
sp
->
pptr
=
cl
->
un
.
inner
.
ptr
+
prio
;
sp
->
pptr
=
cl
->
un
.
inner
.
ptr
+
prio
;
sp
->
pid
=
cl
->
un
.
inner
.
last_ptr_id
+
prio
;
}
}
}
}
BUG_TRAP
(
0
);
BUG_TRAP
(
0
);
...
@@ -1002,7 +1045,8 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
...
@@ -1002,7 +1045,8 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
struct
sk_buff
*
skb
=
NULL
;
struct
sk_buff
*
skb
=
NULL
;
struct
htb_class
*
cl
,
*
start
;
struct
htb_class
*
cl
,
*
start
;
/* look initial class up in the row */
/* look initial class up in the row */
start
=
cl
=
htb_lookup_leaf
(
q
->
row
[
level
]
+
prio
,
prio
,
q
->
ptr
[
level
]
+
prio
);
start
=
cl
=
htb_lookup_leaf
(
HTB_PASSQ
q
->
row
[
level
]
+
prio
,
prio
,
q
->
ptr
[
level
]
+
prio
,
q
->
last_ptr_id
[
level
]
+
prio
);
do
{
do
{
next:
next:
...
@@ -1023,8 +1067,9 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
...
@@ -1023,8 +1067,9 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
if
((
q
->
row_mask
[
level
]
&
(
1
<<
prio
))
==
0
)
if
((
q
->
row_mask
[
level
]
&
(
1
<<
prio
))
==
0
)
return
NULL
;
return
NULL
;
next
=
htb_lookup_leaf
(
q
->
row
[
level
]
+
prio
,
next
=
htb_lookup_leaf
(
HTB_PASSQ
q
->
row
[
level
]
+
prio
,
prio
,
q
->
ptr
[
level
]
+
prio
);
prio
,
q
->
ptr
[
level
]
+
prio
,
q
->
last_ptr_id
[
level
]
+
prio
);
if
(
cl
==
start
)
/* fix start if we just deleted it */
if
(
cl
==
start
)
/* fix start if we just deleted it */
start
=
next
;
start
=
next
;
cl
=
next
;
cl
=
next
;
...
@@ -1039,7 +1084,9 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
...
@@ -1039,7 +1084,9 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
}
}
q
->
nwc_hit
++
;
q
->
nwc_hit
++
;
htb_next_rb_node
((
level
?
cl
->
parent
->
un
.
inner
.
ptr
:
q
->
ptr
[
0
])
+
prio
);
htb_next_rb_node
((
level
?
cl
->
parent
->
un
.
inner
.
ptr
:
q
->
ptr
[
0
])
+
prio
);
cl
=
htb_lookup_leaf
(
q
->
row
[
level
]
+
prio
,
prio
,
q
->
ptr
[
level
]
+
prio
);
cl
=
htb_lookup_leaf
(
HTB_PASSQ
q
->
row
[
level
]
+
prio
,
prio
,
q
->
ptr
[
level
]
+
prio
,
q
->
last_ptr_id
[
level
]
+
prio
);
}
while
(
cl
!=
start
);
}
while
(
cl
!=
start
);
if
(
likely
(
skb
!=
NULL
))
{
if
(
likely
(
skb
!=
NULL
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment