WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[PATCH] Re: [Xen-devel] Time went backwards

On Mon, 13 Mar 2006, Rik van Riel wrote:

> Back to square one...

OK, finally nailed it!   When both stolen and blocked are rounded
down, it is possible for the final increment of the cpu local 
processed_system_time to move the cpu local system time ahead a
bit further than expected - but still proper wrt. wall clock time.

This gives problems on a next timer interrupt, when stolen and
blocked both get rounded up and end up incrementing the per cpu
processed_system_time too far.

These simple checks make sure that the cpu local processed_system_time
never gets advanced too far.  Not advancing the variable now should be
fine, since we'll increment it at the next timer tick...

This patch has made the "time went backwards" error messages go away
completely.

Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>

--- linux-2.6.15.x86_64/arch/i386/kernel/time-xen.c.overflow    2006-03-10 
00:35:53.000000000 -0500
+++ linux-2.6.15.x86_64/arch/i386/kernel/time-xen.c     2006-03-13 
18:02:41.000000000 -0500
@@ -671,6 +671,10 @@
         */
        if (stolen > 0) {
                delta_cpu -= stolen;
+               if (unlikely(delta_cpu < 0)) {
+                       stolen += delta_cpu;
+                       delta_cpu = blocked = 0;
+               }
                do_div(stolen, NS_PER_TICK);
                per_cpu(processed_stolen_time, cpu) += stolen * NS_PER_TICK;
                per_cpu(processed_system_time, cpu) += stolen * NS_PER_TICK;
@@ -684,13 +688,23 @@
         */
        if (blocked > 0) {
                delta_cpu -= blocked;
+               if (unlikely(delta_cpu < 0)) {
+                       blocked += delta_cpu;
+                       delta_cpu = 0;
+               }
                do_div(blocked, NS_PER_TICK);
                per_cpu(processed_blocked_time, cpu) += blocked * NS_PER_TICK;
                per_cpu(processed_system_time, cpu)  += blocked * NS_PER_TICK;
                account_steal_time(idle_task(cpu), (cputime_t)blocked);
        }
 
-       /* Account user/system ticks. */
+       /*
+        * Account user/system ticks.
+        * This gets excess time accounted when blocked and/or stolen get
+        * rounded down, but the "if (delta_cpu < 0)" tests above compensate
+        * for that to keep cpu local processed_system_time from advancing
+        * too far.
+        */
        if (delta_cpu > 0) {
                do_div(delta_cpu, NS_PER_TICK);
                per_cpu(processed_system_time, cpu) += delta_cpu * NS_PER_TICK;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel