[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.