]> xenbits.xensource.com Git - xen.git/commitdiff
[XEN] Fix the timeout workaround so it doesn't capture negative
authorkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Thu, 29 Jun 2006 15:59:47 +0000 (16:59 +0100)
committerkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Thu, 29 Jun 2006 15:59:47 +0000 (16:59 +0100)
diffs relative to current time.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/schedule.c

index cb801040160645f1540e0cc09f5a0c596bf9aed4..cc9947e2798cb63bf27a0a22df6e37194797bb8b 100644 (file)
@@ -389,30 +389,30 @@ long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 long do_set_timer_op(s_time_t timeout)
 {
     struct vcpu *v = current;
+    s_time_t offset = timeout - NOW();
 
     if ( timeout == 0 )
     {
         stop_timer(&v->timer);
     }
+    else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */
+              unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) )
+    {
+        /*
+         * Linux workaround: occasionally we will see timeouts a long way in 
+         * the future due to wrapping in Linux's jiffy time handling. We check 
+         * for timeouts wrapped negative, and for positive timeouts more than 
+         * about 13 days in the future (2^50ns). The correct fix is to trigger 
+         * an interrupt immediately (since Linux in fact has pending work to 
+         * do in this situation).
+         */
+        DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
+                " %"PRIx64"\n",
+                v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
+        send_timer_event(v);
+    }
     else
     {
-        if ( unlikely(timeout < 0) ||
-             unlikely((uint32_t)((timeout - NOW()) >> 50) != 0) )
-        {
-            /*
-             * Linux workaround: occasionally we will see timeouts a long way
-             * in the future due to wrapping in Linux's jiffy time handling.
-             * We check for tiemouts wrapped negative, and for positive
-             * timeouts more than about 13 days in the future (2^50ns).
-             * The correct fix is to trigger an interrupt in a short while
-             * (since Linux in fact has pending work to do in this situation).
-             */
-            DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
-                    " %"PRIx64"\n",
-                    v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
-            timeout = NOW() + MILLISECS(10);
-        }
-
         set_timer(&v->timer, timeout);
     }