1 diff -Nurp linux-2.6.22-200/kernel/vserver/sched.c linux-2.6.22-210/kernel/vserver/sched.c
2 --- linux-2.6.22-200/kernel/vserver/sched.c 2008-04-02 14:03:20.000000000 -0400
3 +++ linux-2.6.22-210/kernel/vserver/sched.c 2008-04-02 15:53:44.000000000 -0400
6 #include <asm/uaccess.h>
9 #define vxd_check_range(val, min, max) do { \
10 vxlprintk((val < min) || (val > max), \
11 "check_range(%ld,%ld,%ld)", \
12 @@ -78,6 +77,11 @@ int vx_tokens_recalc(struct _vx_sched_pc
13 /* how much time did pass? */
14 delta = *norm_time - sched_pc->norm_time;
15 vxd_check_range(delta, 0, INT_MAX);
17 + /* vserver is new or idle for a really long time */
18 + sched_pc->norm_time = *norm_time;
22 if (delta >= sched_pc->interval[0]) {
23 long tokens, integral;
24 @@ -91,7 +97,7 @@ int vx_tokens_recalc(struct _vx_sched_pc
25 vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
28 - sched_pc->norm_time += delta;
29 + sched_pc->norm_time += integral;
32 sched_pc->tokens += tokens;
33 @@ -106,7 +112,12 @@ int vx_tokens_recalc(struct _vx_sched_pc
34 /* how much was the idle skip? */
35 delta = *idle_time - sched_pc->idle_time;
36 vxd_check_range(delta, 0, INT_MAX);
39 + /* vserver is new or idle for a really long time */
40 + sched_pc->idle_time = *idle_time;
44 if (delta >= sched_pc->interval[1]) {
45 long tokens, integral;
47 @@ -161,10 +173,12 @@ on_hold:
49 if (!sched_pc->fill_rate[0])
51 - else if (tokens > sched_pc->fill_rate[0])
52 - delta_min[0] += sched_pc->interval[0] *
53 - tokens / sched_pc->fill_rate[0];
55 + else if (tokens > sched_pc->fill_rate[0]) {
56 + delta_min[0] = sched_pc->interval[0] *
57 + (tokens / sched_pc->fill_rate[0]) - delta_min[0];
58 + if (tokens % sched_pc->fill_rate[0])
59 + delta_min[0] += sched_pc->interval[0];
61 delta_min[0] = sched_pc->interval[0] - delta_min[0];
62 vxd_check_range(delta_min[0], 0, INT_MAX);
64 @@ -175,10 +189,12 @@ on_hold:
66 if (!sched_pc->fill_rate[1])
68 - else if (tokens > sched_pc->fill_rate[1])
69 - delta_min[1] += sched_pc->interval[1] *
70 - tokens / sched_pc->fill_rate[1];
72 + else if (tokens > sched_pc->fill_rate[1]) {
73 + delta_min[1] = sched_pc->interval[1] *
74 + (tokens / sched_pc->fill_rate[1]) - delta_min[1];
75 + if (tokens % sched_pc->fill_rate[1])
76 + delta_min[1] += sched_pc->interval[1];
78 delta_min[1] = sched_pc->interval[1] - delta_min[1];
79 vxd_check_range(delta_min[1], 0, INT_MAX);