x86: Signal softirq-context calibration with an actual first-class
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 27 Aug 2008 09:12:49 +0000 (10:12 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 27 Aug 2008 09:12:49 +0000 (10:12 +0100)
softirq handle rather than kludging it with set_timer().

Should be faster and is definitely clearer. Also avoids us using
set_timer() in IRQ context (which is currently broken but soon won't
be).

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/time.c
xen/include/asm-x86/softirq.h

index 6cbea185cf3ae0cb4da6be940f2d6d08e17c76ac..15d6e4a26cbe5feebb86c221a0dafc078049212a 100644 (file)
@@ -840,12 +840,11 @@ struct cpu_calibration {
     u64 local_tsc_stamp;
     s_time_t stime_local_stamp;
     s_time_t stime_master_stamp;
-    struct timer softirq_callback;
 };
 static DEFINE_PER_CPU(struct cpu_calibration, cpu_calibration);
 
 /* Softirq handler for per-CPU time calibration. */
-static void local_time_calibration(void *unused)
+static void local_time_calibration(void)
 {
     struct cpu_time *t = &this_cpu(cpu_time);
     struct cpu_calibration *c = &this_cpu(cpu_calibration);
@@ -1022,8 +1021,7 @@ static void time_calibration_rendezvous(void *_r)
     c->stime_local_stamp = get_s_time();
     c->stime_master_stamp = r->master_stime;
 
-    /* Callback in softirq context as soon as possible. */
-    set_timer(&c->softirq_callback, c->stime_local_stamp);
+    raise_softirq(TIME_CALIBRATE_SOFTIRQ);
 }
 
 static void time_calibration(void *unused)
@@ -1049,9 +1047,6 @@ void init_percpu_time(void)
     t->stime_master_stamp = now;
     t->stime_local_stamp  = now;
 
-    init_timer(&this_cpu(cpu_calibration).softirq_callback,
-               local_time_calibration, NULL, smp_processor_id());
-
     if ( smp_processor_id() == 0 )
     {
         init_timer(&calibration_timer, time_calibration, NULL, 0);
@@ -1069,6 +1064,8 @@ int __init init_xen_time(void)
     if ( cpuid_edx(0x80000007) & (1u<<8) )
         tsc_invariant = 1;
 
+    open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration);
+
     init_percpu_time();
 
     stime_platform_stamp = 0;
@@ -1176,7 +1173,7 @@ int time_suspend(void)
     }
 
     /* Better to cancel calibration timer for accuracy. */
-    kill_timer(&this_cpu(cpu_calibration).softirq_callback);
+    clear_bit(TIME_CALIBRATE_SOFTIRQ, &softirq_pending(smp_processor_id()));
 
     return 0;
 }
index 5f09a38964a1ad079409aa2a76579425f5143157..12f9d27fb2eacb499999f1fd5b51273c60c9970b 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef __ASM_SOFTIRQ_H__
 #define __ASM_SOFTIRQ_H__
 
-#define NMI_MCE_SOFTIRQ     (NR_COMMON_SOFTIRQS + 0)
+#define NMI_MCE_SOFTIRQ        (NR_COMMON_SOFTIRQS + 0)
+#define TIME_CALIBRATE_SOFTIRQ (NR_COMMON_SOFTIRQS + 1)
 
 #define NR_ARCH_SOFTIRQS    1