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

[Xen-changelog] [xen-unstable] Fix Linux so that it does not set a timeout if there are no pending



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 79f4c91c562864d27a31515d0f7a79d77b2b12a5
# Parent  b066b46122860c927d319d53df7e68d6432c2711
Fix Linux so that it does not set a timeout if there are no pending
timers. Fix Xen so that it does not immediately fire a timer event if
it sees a very long timeout -- sometimes this means that there are
no pending timers.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c |   21 ++++++++++++++-------
 xen/common/schedule.c                            |    7 +++++--
 2 files changed, 19 insertions(+), 9 deletions(-)

diff -r b066b4612286 -r 79f4c91c5628 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Jul 25 16:11:12 
2006 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Jul 25 17:01:49 
2006 +0100
@@ -958,11 +958,17 @@ u64 jiffies_to_st(unsigned long j)
        do {
                seq = read_seqbegin(&xtime_lock);
                delta = j - jiffies;
-               /* NB. The next check can trigger in some wrap-around cases,
-                * but that's ok: we'll just end up with a shorter timeout. */
-               if (delta < 1)
-                       delta = 1;
-               st = processed_system_time + (delta * (u64)NS_PER_TICK);
+               if (delta < 1) {
+                       /* Triggers in some wrap-around cases, but that's okay:
+                        * we just end up with a shorter timeout. */
+                       st = processed_system_time + NS_PER_TICK;
+               } else if (((unsigned long)delta >> (BITS_PER_LONG-3)) != 0) {
+                       /* Very long timeout means there is no pending timer.
+                        * We indicate this to Xen by passing zero timeout. */
+                       st = 0;
+               } else {
+                       st = processed_system_time + delta * (u64)NS_PER_TICK;
+               }
        } while (read_seqretry(&xtime_lock, seq));
 
        return st;
@@ -989,14 +995,15 @@ static void stop_hz_timer(void)
 
        smp_mb();
 
-       /* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
+       /* Leave ourselves in tick mode if rcu or softirq or timer pending. */
        if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
            (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
                cpu_clear(cpu, nohz_cpu_mask);
                j = jiffies + 1;
        }
 
-       BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
+       if (HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0)
+               BUG();
 }
 
 static void start_hz_timer(void)
diff -r b066b4612286 -r 79f4c91c5628 xen/common/schedule.c
--- a/xen/common/schedule.c     Tue Jul 25 16:11:12 2006 +0100
+++ b/xen/common/schedule.c     Tue Jul 25 17:01:49 2006 +0100
@@ -404,12 +404,15 @@ long do_set_timer_op(s_time_t timeout)
          * 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).
+         * do in this situation). However, older guests also set a long timeout
+         * when they have *no* pending timers at all: setting an immediate
+         * timeout in this case can burn a lot of CPU. We therefore go for a
+         * reasonable middleground of triggering a timer event in 100ms.
          */
         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);
+        set_timer(&v->timer, NOW() + MILLISECS(100));
     }
     else
     {

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


 


Rackspace

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