Fix for when slice has been idle for a long time
[linux-2.6.git] / linux-2.6-210-vserver-cpu-sched.patch
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
4 @@ -18,7 +18,6 @@
5  
6  #include <asm/uaccess.h>
7  
8 -
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);
16 +       if (delta < 0) {
17 +               /* vserver is new or idle for a really long time */
18 +               sched_pc->norm_time = *norm_time;
19 +               delta = 0;
20 +       }
21  
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]);
26  #endif
27                 /* advance time */
28 -               sched_pc->norm_time += delta;
29 +               sched_pc->norm_time += integral;
30  
31                 /* add tokens */
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);
37 -
38 +       if (delta < 0) {
39 +               /* vserver is new or idle for a really long time */
40 +               sched_pc->idle_time = *idle_time;
41 +               delta = 0;
42 +       }
43 +       
44         if (delta >= sched_pc->interval[1]) {
45                 long tokens, integral;
46  
47 @@ -161,10 +173,12 @@ on_hold:
48         /* next interval? */
49         if (!sched_pc->fill_rate[0])
50                 delta_min[0] = HZ;
51 -       else if (tokens > sched_pc->fill_rate[0])
52 -               delta_min[0] += sched_pc->interval[0] *
53 -                       tokens / sched_pc->fill_rate[0];
54 -       else
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]; 
60 +       } else 
61                 delta_min[0] = sched_pc->interval[0] - delta_min[0];
62         vxd_check_range(delta_min[0], 0, INT_MAX);
63  
64 @@ -175,10 +189,12 @@ on_hold:
65         /* next interval? */
66         if (!sched_pc->fill_rate[1])
67                 delta_min[1] = HZ;
68 -       else if (tokens > sched_pc->fill_rate[1])
69 -               delta_min[1] += sched_pc->interval[1] *
70 -                       tokens / sched_pc->fill_rate[1];
71 -       else
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];
77 +       } else
78                 delta_min[1] = sched_pc->interval[1] - delta_min[1];
79         vxd_check_range(delta_min[1], 0, INT_MAX);
80