diff -Nurp linux-2.6.22-200/kernel/vserver/sched.c linux-2.6.22-210/kernel/vserver/sched.c
---- linux-2.6.22-200/kernel/vserver/sched.c 2008-03-20 17:15:35.000000000 -0400
-+++ linux-2.6.22-210/kernel/vserver/sched.c 2008-03-31 17:55:55.000000000 -0400
-@@ -91,7 +91,7 @@ int vx_tokens_recalc(struct _vx_sched_pc
+--- linux-2.6.22-200/kernel/vserver/sched.c 2008-04-02 14:03:20.000000000 -0400
++++ linux-2.6.22-210/kernel/vserver/sched.c 2008-04-02 15:53:44.000000000 -0400
+@@ -18,7 +18,6 @@
+
+ #include <asm/uaccess.h>
+
+-
+ #define vxd_check_range(val, min, max) do { \
+ vxlprintk((val < min) || (val > max), \
+ "check_range(%ld,%ld,%ld)", \
+@@ -78,6 +77,11 @@ int vx_tokens_recalc(struct _vx_sched_pc
+ /* how much time did pass? */
+ delta = *norm_time - sched_pc->norm_time;
+ vxd_check_range(delta, 0, INT_MAX);
++ if (delta < 0) {
++ /* vserver is new or idle for a really long time */
++ sched_pc->norm_time = *norm_time;
++ delta = 0;
++ }
+
+ if (delta >= sched_pc->interval[0]) {
+ long tokens, integral;
+@@ -91,7 +97,7 @@ int vx_tokens_recalc(struct _vx_sched_pc
vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
#endif
/* advance time */
/* add tokens */
sched_pc->tokens += tokens;
-@@ -161,10 +161,12 @@ on_hold:
+@@ -106,7 +112,12 @@ int vx_tokens_recalc(struct _vx_sched_pc
+ /* how much was the idle skip? */
+ delta = *idle_time - sched_pc->idle_time;
+ vxd_check_range(delta, 0, INT_MAX);
+-
++ if (delta < 0) {
++ /* vserver is new or idle for a really long time */
++ sched_pc->idle_time = *idle_time;
++ delta = 0;
++ }
++
+ if (delta >= sched_pc->interval[1]) {
+ long tokens, integral;
+
+@@ -161,10 +173,12 @@ on_hold:
/* next interval? */
if (!sched_pc->fill_rate[0])
delta_min[0] = HZ;
delta_min[0] = sched_pc->interval[0] - delta_min[0];
vxd_check_range(delta_min[0], 0, INT_MAX);
-@@ -175,10 +177,12 @@ on_hold:
+@@ -175,10 +189,12 @@ on_hold:
/* next interval? */
if (!sched_pc->fill_rate[1])
delta_min[1] = HZ;
- else if (tokens > sched_pc->fill_rate[1])
-+ else if (tokens > sched_pc->fill_rate[1]) {
- delta_min[1] += sched_pc->interval[1] *
+- delta_min[1] += sched_pc->interval[1] *
- tokens / sched_pc->fill_rate[1];
- else
-+ tokens / sched_pc->fill_rate[1] - delta_min[1];
++ else if (tokens > sched_pc->fill_rate[1]) {
++ delta_min[1] = sched_pc->interval[1] *
++ (tokens / sched_pc->fill_rate[1]) - delta_min[1];
+ if (tokens % sched_pc->fill_rate[1])
+ delta_min[1] += sched_pc->interval[1];
+ } else