bitkeeper revision 1.1159.264.1 (422d7683GAA5eJb-zpm3NsgvYf9Q9A)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 8 Mar 2005 09:55:15 +0000 (09:55 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 8 Mar 2005 09:55:15 +0000 (09:55 +0000)
Clean up timer upcalls to guest kernel. Only send an upcall when
timestamp info actually changes.
Signed-off-by: Keir Fraser <keir.fraser@cl.cam.ac.uk>
BitKeeper/etc/logging_ok
xen/arch/x86/domain.c
xen/arch/x86/time.c
xen/common/domain.c
xen/common/schedule.c
xen/include/xen/sched.h
xen/include/xen/time.h

index 935727fd0bc4bfc5044afcac99e7db8179df3895..d54268186edad91f96dea3424a07f60bd25fb96b 100644 (file)
@@ -27,6 +27,7 @@ iap10@tetris.cl.cam.ac.uk
 jws22@gauntlet.cl.cam.ac.uk
 jws@cairnwell.research
 kaf24@camelot.eng.3leafnetworks.com
+kaf24@firebug.cl.cam.ac.uk
 kaf24@freefall.cl.cam.ac.uk
 kaf24@labyrinth.cl.cam.ac.uk
 kaf24@penguin.local
index 21cfdd9515b07af55b34202c6d838bc0bcf2e2f8..9c81c9c7182605464425e9db1e9d85daef6b62c3 100644 (file)
@@ -869,9 +869,6 @@ int construct_dom0(struct domain *p,
             l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab);
     }
 
-    /* Set up shared-info area. */
-    update_dom_time(p->shared_info);
-    p->shared_info->domain_time = 0;
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
         p->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
index be9f477ba58df6d6ae022f4ebcb32ef8e69a39e3..685160cd14c426eee2141c2cc130e6a9167ca3d7 100644 (file)
@@ -14,7 +14,9 @@
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
  */
 
+#include <xen/config.h>
 #include <xen/errno.h>
+#include <xen/event.h>
 #include <xen/sched.h>
 #include <xen/lib.h>
 #include <xen/config.h>
@@ -274,12 +276,18 @@ s_time_t get_s_time(void)
 }
 
 
-void update_dom_time(shared_info_t *si)
+void update_dom_time(struct domain *d)
 {
+    shared_info_t *si = d->shared_info;
     unsigned long flags;
 
+    if ( d->last_propagated_timestamp == full_tsc_irq )
+        return;
+
     read_lock_irqsave(&time_lock, flags);
 
+    d->last_propagated_timestamp = full_tsc_irq;
+    
     si->time_version1++;
     wmb();
 
@@ -293,6 +301,8 @@ void update_dom_time(shared_info_t *si)
     si->time_version2++;
 
     read_unlock_irqrestore(&time_lock, flags);
+
+    send_guest_virq(d, VIRQ_TIMER);
 }
 
 
@@ -318,7 +328,9 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
 
     write_unlock_irq(&time_lock);
 
-    update_dom_time(current->shared_info);
+    /* Others will pick up the change at the next tick. */
+    current->last_propagated_timestamp = 0; /* force propagation */
+    update_dom_time(current);
 }
 
 
index c2fe184267627017da3cc7fa09d48118bb0f2347..47673b21ec92aa0983b8bcfb8e279efcbd3e7d66 100644 (file)
@@ -267,9 +267,6 @@ int final_setup_guestos(struct domain *p, dom0_builddomain_t *builddomain)
     if ( (rc = arch_final_setup_guestos(p,c)) != 0 )
         goto out;
 
-    /* Set up the shared info structure. */
-    update_dom_time(p->shared_info);
-
     set_bit(DF_CONSTRUCTED, &p->flags);
 
  out:    
index ec215d5ed9a3fda253a819940c043e1c8826444e..09c3e77ad9701a9d359d65cb0e9bbc4012ee43ad 100644 (file)
@@ -358,10 +358,6 @@ void __enter_scheduler(void)
 
     spin_unlock_irq(&schedule_data[cpu].schedule_lock);
 
-    /* Ensure that the domain has an up-to-date time base. */
-    if ( !is_idle_task(next) )
-        update_dom_time(next->shared_info);
-
     if ( unlikely(prev == next) )
         return;
     
@@ -399,10 +395,10 @@ void __enter_scheduler(void)
      */
     clear_bit(DF_RUNNING, &prev->flags);
 
-    /* Mark a timer event for the newly-scheduled domain. */
+    /* Ensure that the domain has an up-to-date time base. */
     if ( !is_idle_task(next) )
-        send_guest_virq(next, VIRQ_TIMER);
-    
+        update_dom_time(next);
+
     schedule_tail(next);
 
     BUG();
@@ -439,10 +435,7 @@ static void t_timer_fn(unsigned long unused)
     TRACE_0D(TRC_SCHED_T_TIMER_FN);
 
     if ( !is_idle_task(d) )
-    {
-        update_dom_time(d->shared_info);
-        send_guest_virq(d, VIRQ_TIMER);
-    }
+        update_dom_time(d);
 
     t_timer[d->processor].expires = NOW() + MILLISECS(10);
     add_ac_timer(&t_timer[d->processor]);
@@ -453,8 +446,7 @@ static void dom_timer_fn(unsigned long data)
 {
     struct domain *d = (struct domain *)data;
     TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
-    update_dom_time(d->shared_info);
-    send_guest_virq(d, VIRQ_TIMER);
+    update_dom_time(d);
 }
 
 /* Initialise the data structures. */
index d7e6f0be26edb0f3f7f7229ad5f711ceef2b4a9b..254169cd9ffe06a26275764be4ff2b022f852d4e 100644 (file)
@@ -102,6 +102,9 @@ struct domain
     u16 virq_to_evtchn[NR_VIRQS];
     u32 pirq_mask[NR_PIRQS/32];
 
+    /* Last point at which timestamp info was propagated to the guest. */
+    u64 last_propagated_timestamp;
+
     /* Physical I/O */
     spinlock_t       pcidev_lock;
     struct list_head pcidev_list;
index dd476f9298c1a45d09d0ddc294b94465ccf24bf5..e725c4ed94efa876cb442a87c1321edefb50cd85 100644 (file)
@@ -52,7 +52,8 @@ s_time_t get_s_time(void);
 #define MILLISECS(_ms)  (((s_time_t)(_ms)) * 1000000ULL )
 #define MICROSECS(_us)  (((s_time_t)(_us)) * 1000ULL )
 
-extern void update_dom_time(shared_info_t *si);
+struct domain;
+extern void update_dom_time(struct domain *d);
 extern void do_settime(unsigned long secs, unsigned long usecs, 
                        u64 system_time_base);