git://git.onelab.eu
/
linux-2.6.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
7dec203
)
Fixed an overflow bug with div_long_long_rem
author
Andy Bavier
<acb@cs.princeton.edu>
Fri, 11 Nov 2005 18:15:55 +0000
(18:15 +0000)
committer
Andy Bavier
<acb@cs.princeton.edu>
Fri, 11 Nov 2005 18:15:55 +0000
(18:15 +0000)
kernel/vserver/sched.c
patch
|
blob
|
history
diff --git
a/kernel/vserver/sched.c
b/kernel/vserver/sched.c
index
e978e7a
..
5aae959
100644
(file)
--- a/
kernel/vserver/sched.c
+++ b/
kernel/vserver/sched.c
@@
-34,9
+34,12
@@
uint64_t vx_best_effort_ticks = 0;
void vx_tokens_set(struct vx_info *vxi, int tokens) {
int class = CLASS(vxi);
void vx_tokens_set(struct vx_info *vxi, int tokens) {
int class = CLASS(vxi);
+ uint64_t tmp;
+
+ tmp = GLOBAL_TICKS(vxi);
+ tmp -= tokens * TICKS_PER_TOKEN(vxi);
- vxi->sched.ticks[class] = GLOBAL_TICKS(vxi);
- vxi->sched.ticks[class] -= tokens * TICKS_PER_TOKEN(vxi);
+ vxi->sched.ticks[class] = tmp;
}
void vx_scheduler_tick(void) {
}
void vx_scheduler_tick(void) {
@@
-54,9
+57,9
@@
void vx_advance_guaranteed_ticks(int ticks) {
int vx_tokens_avail(struct vx_info *vxi)
{
int vx_tokens_avail(struct vx_info *vxi)
{
- uint64_t diff;
+ uint64_t diff
, max_ticks
;
int tokens;
int tokens;
- long rem;
+ long
tpt,
rem;
int class = CLASS(vxi);
if (vxi->sched.state[class] == SCH_UNINITIALIZED) {
int class = CLASS(vxi);
if (vxi->sched.state[class] == SCH_UNINITIALIZED) {
@@
-75,12
+78,17
@@
int vx_tokens_avail(struct vx_info *vxi)
/* Use of fixed-point arithmetic in these calculations leads to
* some limitations. These should be made explicit.
*/
/* Use of fixed-point arithmetic in these calculations leads to
* some limitations. These should be made explicit.
*/
+ max_ticks = (tpt = TICKS_PER_TOKEN(vxi));
+ max_ticks *= vxi->sched.tokens_max;
diff = GLOBAL_TICKS(vxi) - vxi->sched.ticks[class];
diff = GLOBAL_TICKS(vxi) - vxi->sched.ticks[class];
- tokens = div_long_long_rem(diff, TICKS_PER_TOKEN(vxi), &rem);
- if (tokens > vxi->sched.tokens_max) {
+ /* Avoid an overflow from div_long_long_rem */
+ if (diff >= max_ticks) {
vx_tokens_set(vxi, vxi->sched.tokens_max);
tokens = vxi->sched.tokens_max;
vx_tokens_set(vxi, vxi->sched.tokens_max);
tokens = vxi->sched.tokens_max;
+ } else {
+ /* Divide ticks by ticks per token to get tokens */
+ tokens = div_long_long_rem(diff, tpt, &rem);
}
atomic_set(&vxi->sched.tokens, tokens);
}
atomic_set(&vxi->sched.tokens, tokens);
@@
-95,6
+103,7
@@
void vx_consume_token(struct vx_info *vxi)
int class = CLASS(vxi);
vxi->sched.ticks[class] += TICKS_PER_TOKEN(vxi);
int class = CLASS(vxi);
vxi->sched.ticks[class] += TICKS_PER_TOKEN(vxi);
+ atomic_dec(&vxi->sched.tokens);
}
/*
}
/*