ia64/xen-unstable
changeset 183:db2f43dad304
bitkeeper revision 1.33.2.1 (3e4e80bfKovSGNhpWOvbDx2coqfMIw)
clean up of time/timer code: No PIT timer anymore and bugfixes to timer code
clean up of time/timer code: No PIT timer anymore and bugfixes to timer code
author | rn@wyvis.camb.intel-research.net |
---|---|
date | Sat Feb 15 18:02:39 2003 +0000 (2003-02-15) |
parents | 53760d4155cf |
children | 30e08b71439f |
files | xen-2.4.16/arch/i386/apic.c xen-2.4.16/arch/i386/i8259.c xen-2.4.16/arch/i386/setup.c xen-2.4.16/arch/i386/time.c xen-2.4.16/common/ac_timer.c xen-2.4.16/common/schedule.c xen-2.4.16/common/timer.c xen-2.4.16/include/asm-i386/time.h |
line diff
1.1 --- a/xen-2.4.16/arch/i386/apic.c Fri Feb 14 13:18:19 2003 +0000 1.2 +++ b/xen-2.4.16/arch/i386/apic.c Sat Feb 15 18:02:39 2003 +0000 1.3 @@ -697,37 +697,29 @@ int reprogram_ac_timer(s_time_t timeout) 1.4 * the timer APIC on CPU does not go off every 10ms or so the linux 1.5 * timers loose accuracy, but that shouldn't be a problem. 1.6 */ 1.7 -//static s_time_t last_cpu0_tirq = 0; 1.8 +static s_time_t last_cpu0_tirq = 0; 1.9 inline void smp_local_timer_interrupt(struct pt_regs * regs) 1.10 { 1.11 int cpu = smp_processor_id(); 1.12 - //s_time_t diff, now; 1.13 + s_time_t diff, now; 1.14 + 1.15 1.16 /* if CPU 0 do old timer stuff */ 1.17 if (cpu == 0) { 1.18 1.19 - /* 1.20 - * XXX RN: the following code should be moved here or somewhere 1.21 - * else. It's currently done using the 8255 timer interrupt, which 1.22 - * I'd like to disable. But, APIC initialisation relies on it, 1.23 - * e.g., timer interrupts coming in, jiffies going up, etc. Need to 1.24 - * clean this up. Also see ./arch/i386/time.c 1.25 - */ 1.26 -#if 0 1.27 - //update_time();/* XXX should use a timer for this */ 1.28 now = NOW(); 1.29 diff = now - last_cpu0_tirq; 1.30 1.31 - /* this uses three 64bit divisions which should be avoided!! */ 1.32 - if (diff >= MILLISECS(10)) { 1.33 - /* update jiffies */ 1.34 - (*(unsigned long *)&jiffies) += diff / MILLISECS(10); 1.35 + if (diff <= 0) { 1.36 + printk ("System Time went backwards: %lld\n", diff); 1.37 + return; 1.38 + } 1.39 1.40 - /* do traditional linux timers */ 1.41 + while (diff >= MILLISECS(10)) { 1.42 do_timer(regs); 1.43 - last_cpu0_tirq = now; 1.44 + diff -= MILLISECS(10); 1.45 + last_cpu0_tirq += MILLISECS(10); 1.46 } 1.47 -#endif 1.48 } 1.49 /* call accurate timer function */ 1.50 do_ac_timer();
2.1 --- a/xen-2.4.16/arch/i386/i8259.c Fri Feb 14 13:18:19 2003 +0000 2.2 +++ b/xen-2.4.16/arch/i386/i8259.c Sat Feb 15 18:02:39 2003 +0000 2.3 @@ -467,3 +467,15 @@ void __init init_IRQ(void) 2.4 2.5 setup_irq(2, &irq2); 2.6 } 2.7 + 2.8 +/* 2.9 + * we only need the timer interrupt for callibrating the tsc<->time<->bus cycle 2.10 + * mappings. After this all timeing related functions should be run of the 2.11 + * APIC timers. This function allows us to disable the 2.12 + */ 2.13 +void __init disable_pit(void) 2.14 +{ 2.15 + printk("Disable PIT. Not needed anymore\n"); 2.16 + /* This is not the most elegant way, but hey. */ 2.17 + disable_irq(0); 2.18 +}
3.1 --- a/xen-2.4.16/arch/i386/setup.c Fri Feb 14 13:18:19 2003 +0000 3.2 +++ b/xen-2.4.16/arch/i386/setup.c Sat Feb 15 18:02:39 2003 +0000 3.3 @@ -280,6 +280,7 @@ void __init start_of_day(void) 3.4 extern void tqueue_bh(void); 3.5 extern void immediate_bh(void); 3.6 extern void init_timervecs(void); 3.7 + extern void disable_pit(void); 3.8 extern void ac_timer_init(void); 3.9 extern int setup_network_devices(void); 3.10 extern void net_init(void); 3.11 @@ -329,8 +330,11 @@ void __init start_of_day(void) 3.12 * fall thru to 8259A if we have to (but slower). 3.13 */ 3.14 #endif 3.15 + initialize_keytable(); /* call back handling for key codes */ 3.16 + 3.17 + disable_pit(); /* not needed anymore */ 3.18 + ac_timer_init(); /* init accurate timers */ 3.19 init_xeno_time(); /* initialise the time */ 3.20 - ac_timer_init(); /* init accurate timers */ 3.21 schedulers_start(); /* start scheduler for each CPU */ 3.22 3.23 sti(); 3.24 @@ -343,7 +347,7 @@ void __init start_of_day(void) 3.25 #endif 3.26 do_initcalls(); 3.27 3.28 - initialize_keytable(); /* call back handling for key codes */ 3.29 + 3.30 initialize_serial(); /* setup serial 'driver' (for debugging) */ 3.31 initialize_keyboard(); /* setup keyboard (also for debugging) */ 3.32
4.1 --- a/xen-2.4.16/arch/i386/time.c Fri Feb 14 13:18:19 2003 +0000 4.2 +++ b/xen-2.4.16/arch/i386/time.c Sat Feb 15 18:02:39 2003 +0000 4.3 @@ -31,6 +31,7 @@ 4.4 #include <xeno/init.h> 4.5 #include <xeno/interrupt.h> 4.6 #include <xeno/time.h> 4.7 +#include <xeno/ac_timer.h> 4.8 4.9 #include <asm/io.h> 4.10 #include <xeno/smp.h> 4.11 @@ -74,15 +75,12 @@ static inline void do_timer_interrupt(in 4.12 spin_unlock(&i8259A_lock); 4.13 } 4.14 #endif 4.15 - 4.16 - /* XXX RN: Want to remove this but APIC-SMP code seems to rely on it */ 4.17 do_timer(regs); 4.18 } 4.19 4.20 /* 4.21 - * This is the same as the above, except we _also_ save the current 4.22 - * Time Stamp Counter value at the time of the timer interrupt, so that 4.23 - * we later on can estimate the time of day more exactly. 4.24 + * This is only temporarily. Once the APIC s up and running this 4.25 + * timer interrupt is turned off. 4.26 */ 4.27 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 4.28 { 4.29 @@ -303,8 +301,34 @@ void do_settimeofday(struct timeval *tv) 4.30 /*************************************************************************** 4.31 * Update times 4.32 ***************************************************************************/ 4.33 -/* update hypervisors notion of time */ 4.34 -void update_time(void) { 4.35 + 4.36 +/* update a domains notion of time */ 4.37 +void update_dom_time(shared_info_t *si) 4.38 +{ 4.39 + unsigned long flags; 4.40 + 4.41 + spin_lock_irqsave(&stime_lock, flags); 4.42 + si->system_time = stime_now; 4.43 + si->st_timestamp = stime_pcc; 4.44 + spin_unlock_irqrestore(&stime_lock, flags); 4.45 + 4.46 + spin_lock_irqsave(&wctime_lock, flags); 4.47 + si->tv_sec = wall_clock_time.tv_sec; 4.48 + si->tv_usec = wall_clock_time.tv_usec; 4.49 + si->wc_timestamp = wctime_st; 4.50 + si->wc_version++; 4.51 + spin_unlock_irqrestore(&wctime_lock, flags); 4.52 + 4.53 + TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st)); 4.54 +} 4.55 + 4.56 +/* 4.57 + * Update hypervisors notion of time 4.58 + * This is done periodically of it's own timer 4.59 + */ 4.60 +static struct ac_timer update_timer; 4.61 +static void update_time(unsigned long foo) 4.62 +{ 4.63 unsigned long flags; 4.64 u32 new_pcc; 4.65 s_time_t new_st; 4.66 @@ -336,26 +360,12 @@ void update_time(void) { 4.67 TRC(printk("TIME[%02d] update time: stime_now=%lld now=%lld,wct=%ld:%ld\n", 4.68 smp_processor_id(), stime_now, new_st, wall_clock_time.tv_sec, 4.69 wall_clock_time.tv_usec)); 4.70 -} 4.71 - 4.72 -/* update a domains notion of time */ 4.73 -void update_dom_time(shared_info_t *si) 4.74 -{ 4.75 - unsigned long flags; 4.76 - 4.77 - spin_lock_irqsave(&stime_lock, flags); 4.78 - si->system_time = stime_now; 4.79 - si->st_timestamp = stime_pcc; 4.80 - spin_unlock_irqrestore(&stime_lock, flags); 4.81 - 4.82 - spin_lock_irqsave(&wctime_lock, flags); 4.83 - si->tv_sec = wall_clock_time.tv_sec; 4.84 - si->tv_usec = wall_clock_time.tv_usec; 4.85 - si->wc_timestamp = wctime_st; 4.86 - si->wc_version++; 4.87 - spin_unlock_irqrestore(&wctime_lock, flags); 4.88 - 4.89 - TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st)); 4.90 + /* reload timer */ 4.91 + again: 4.92 + update_timer.expires = new_st + MILLISECS(200); 4.93 + if(add_ac_timer(&update_timer) == 1) { 4.94 + goto again; 4.95 + } 4.96 } 4.97 4.98 /*************************************************************************** 4.99 @@ -364,13 +374,15 @@ void update_dom_time(shared_info_t *si) 4.100 ***************************************************************************/ 4.101 int __init init_xeno_time() 4.102 { 4.103 - int cpu = smp_processor_id(); 4.104 - u32 cpu_cycle; /* time of one cpu cyle in pico-seconds */ 4.105 - u64 scale; 4.106 + int cpu = smp_processor_id(); 4.107 + u32 cpu_cycle; /* time of one cpu cyle in pico-seconds */ 4.108 + u64 scale; /* scale factor */ 4.109 4.110 spin_lock_init(&stime_lock); 4.111 spin_lock_init(&wctime_lock); 4.112 4.113 + printk("Init Time[%02d]:\n", cpu); 4.114 + 4.115 /* System Time */ 4.116 cpu_cycle = (u32) (1000000000LL/cpu_khz); /* in pico seconds */ 4.117 scale = 1000000000LL << 32; 4.118 @@ -378,24 +390,30 @@ int __init init_xeno_time() 4.119 st_scale_f = scale & 0xffffffff; 4.120 st_scale_i = scale >> 32; 4.121 4.122 - stime_now = (s_time_t)0; 4.123 - rdtscl(stime_pcc); 4.124 - 4.125 - printk("Init Time[%02d]:\n", cpu); 4.126 - printk(".... System Time: %lldns\n", NOW()); 4.127 - printk(".....cpu_cycle: %u ps\n", cpu_cycle); 4.128 - printk(".... st_scale_f: %X\n", st_scale_f); 4.129 - printk(".... st_scale_i: %X\n", st_scale_i); 4.130 - printk(".... stime_pcc: %u\n", stime_pcc); 4.131 - 4.132 /* Wall Clock time */ 4.133 wall_clock_time.tv_sec = get_cmos_time(); 4.134 wall_clock_time.tv_usec = 0; 4.135 + 4.136 + /* set starting times */ 4.137 + stime_now = (s_time_t)0; 4.138 + rdtscl(stime_pcc); 4.139 wctime_st = NOW(); 4.140 4.141 + /* start timer to update time periodically */ 4.142 + init_ac_timer(&update_timer); 4.143 + update_timer.function = &update_time; 4.144 + update_time(0); 4.145 + 4.146 + printk(".... System Time: %lldns\n", NOW()); 4.147 + printk(".....cpu_cycle: %u ps\n", cpu_cycle); 4.148 + printk(".... st_scale_f: %X\n", st_scale_f); 4.149 + printk(".... st_scale_i: %X\n", st_scale_i); 4.150 + printk(".... stime_pcc: %u\n", stime_pcc); 4.151 + 4.152 printk(".... Wall Clock: %lds %ldus\n", wall_clock_time.tv_sec, 4.153 wall_clock_time.tv_usec); 4.154 printk(".... wctime_st: %lld\n", wctime_st); 4.155 + 4.156 return 0; 4.157 } 4.158
5.1 --- a/xen-2.4.16/common/ac_timer.c Fri Feb 14 13:18:19 2003 +0000 5.2 +++ b/xen-2.4.16/common/ac_timer.c Sat Feb 15 18:02:39 2003 +0000 5.3 @@ -29,6 +29,7 @@ 5.4 5.5 #include <xeno/time.h> 5.6 #include <xeno/ac_timer.h> 5.7 +#include <xeno/keyhandler.h> 5.8 5.9 #include <asm/system.h> 5.10 #include <asm/desc.h> 5.11 @@ -80,8 +81,6 @@ int add_ac_timer(struct ac_timer *timer) 5.12 { 5.13 int cpu = smp_processor_id(); 5.14 unsigned long flags; 5.15 - struct list_head *tmp, *prev; 5.16 - struct ac_timer *t; 5.17 s_time_t now; 5.18 5.19 /* sanity checks */ 5.20 @@ -96,42 +95,54 @@ int add_ac_timer(struct ac_timer *timer) 5.21 (u32)(timer->expires>>32), (u32)timer->expires); 5.22 return 1; 5.23 } 5.24 - 5.25 - local_irq_save(flags); 5.26 - 5.27 - /* check if timer would be inserted at start of list */ 5.28 - if ((list_empty(&ac_timers[cpu].timers)) || 5.29 - (timer->expires < 5.30 - (list_entry(&ac_timers[cpu].timers, 5.31 - struct ac_timer, timer_list))->expires)) { 5.32 - 5.33 - TRC(printk("ACT [%02d] add(): add at head\n", cpu)); 5.34 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 5.35 + /* 5.36 + * Add timer to the list. If it gets added to the front we have to 5.37 + * reprogramm the timer 5.38 + */ 5.39 + if (list_empty(&ac_timers[cpu].timers)) { 5.40 /* Reprogramm and add to head of list */ 5.41 if (!reprogram_ac_timer(timer->expires)) { 5.42 /* failed */ 5.43 - TRC(printk("ACT [%02d] add(): add at head failed\n", cpu)); 5.44 - local_irq_restore(flags); 5.45 + printk("ACT [%02d] add(): add at head failed\n", cpu); 5.46 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.47 return 1; 5.48 } 5.49 list_add(&timer->timer_list, &ac_timers[cpu].timers); 5.50 - 5.51 + TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 5.52 + (u32)(timer->expires>>32), (u32)timer->expires)); 5.53 } else { 5.54 - /* find correct entry and add timer */ 5.55 - prev = &ac_timers[cpu].timers; 5.56 - list_for_each(tmp, &ac_timers[cpu].timers) { 5.57 - t = list_entry(tmp, struct ac_timer, timer_list); 5.58 - if (t->expires < timer->expires) { 5.59 - list_add(&timer->timer_list, prev); 5.60 - TRC(printk("ACT [%02d] add(): added between %lld and %lld\n", 5.61 + struct list_head *pos; 5.62 + struct ac_timer *t; 5.63 + for (pos = ac_timers[cpu].timers.next; 5.64 + pos != &ac_timers[cpu].timers; 5.65 + pos = pos->next) { 5.66 + t = list_entry(pos, struct ac_timer, timer_list); 5.67 + if (t->expires > timer->expires) 5.68 + break; 5.69 + } 5.70 + 5.71 + if (pos->prev == &ac_timers[cpu].timers) { 5.72 + /* added to head, reprogramm timer */ 5.73 + if (!reprogram_ac_timer(timer->expires)) { 5.74 + /* failed */ 5.75 + TRC(printk("ACT [%02d] add(): add at head failed\n", cpu)); 5.76 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.77 + return 1; 5.78 + } 5.79 + list_add (&(timer->timer_list), pos->prev); 5.80 + TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 5.81 + (u32)(timer->expires>>32), (u32)timer->expires)); 5.82 + } else { 5.83 + list_add (&(timer->timer_list), pos->prev); 5.84 + TRC(printk("ACT [%02d] add(0x%08X%08X): add < exp=0x%08X%08X\n", 5.85 cpu, 5.86 - list_entry(prev,struct ac_timer,timer_list)->expires, 5.87 - list_entry(tmp,struct ac_timer,timer_list)->expires)); 5.88 - break; 5.89 - } 5.90 - prev = tmp; 5.91 + (u32)(timer->expires>>32), (u32)timer->expires, 5.92 + (u32)(t->expires>>32), (u32)t->expires)); 5.93 } 5.94 + 5.95 } 5.96 - local_irq_restore(flags); 5.97 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.98 return 0; 5.99 } 5.100 5.101 @@ -158,16 +169,17 @@ static int detach_ac_timer(struct ac_tim 5.102 */ 5.103 int rem_ac_timer(struct ac_timer *timer) 5.104 { 5.105 - int res; 5.106 + int cpu = smp_processor_id(); 5.107 + int res; 5.108 unsigned long flags; 5.109 - TRC(int cpu = smp_processor_id()); 5.110 5.111 TRC(printk("ACT [%02d] remove(): timo=%lld \n", cpu, timer->expires)); 5.112 /* sanity checks */ 5.113 5.114 - local_irq_save(flags); 5.115 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 5.116 res = detach_ac_timer(timer); 5.117 - local_irq_restore(flags); 5.118 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.119 + 5.120 return res; 5.121 } 5.122 5.123 @@ -199,7 +211,7 @@ void do_ac_timer(void) 5.124 struct ac_timer *t; 5.125 struct list_head *tmp; 5.126 5.127 - local_irq_save(flags); 5.128 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 5.129 5.130 do_timer_again: 5.131 5.132 @@ -210,7 +222,7 @@ void do_ac_timer(void) 5.133 /* empty time list */ 5.134 if (list_empty(&ac_timers[cpu].timers)) { 5.135 printk("ACT[%02d] do_ac_timer(): timer irq without timer\n", cpu); 5.136 - local_irq_restore(flags); 5.137 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.138 return; 5.139 } 5.140 5.141 @@ -219,6 +231,8 @@ void do_ac_timer(void) 5.142 t = list_entry(ac_timers[cpu].timers.next, struct ac_timer, timer_list); 5.143 detach_ac_timer(t); 5.144 5.145 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.146 + 5.147 5.148 #ifdef AC_TIMER_STATS 5.149 { 5.150 @@ -258,6 +272,9 @@ void do_ac_timer(void) 5.151 5.152 /* check if there are other timer functions on the list */ 5.153 now = NOW(); 5.154 + 5.155 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 5.156 + 5.157 if (!list_empty(&ac_timers[cpu].timers)) { 5.158 list_for_each(tmp, &ac_timers[cpu].timers) { 5.159 t = list_entry(tmp, struct ac_timer, timer_list); 5.160 @@ -265,8 +282,10 @@ void do_ac_timer(void) 5.161 cpu, now, t->expires)); 5.162 if (t->expires <= now) { 5.163 detach_ac_timer(t); 5.164 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.165 if (t->function != NULL) 5.166 t->function(t->data); 5.167 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 5.168 now = NOW(); 5.169 } else { 5.170 TRC(printk("ACT [%02d] do(): break1\n", cpu)); 5.171 @@ -286,7 +305,47 @@ void do_ac_timer(void) 5.172 } 5.173 } 5.174 } 5.175 - local_irq_restore(flags); 5.176 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 5.177 + TRC(printk("ACT [%02d] do(): end\n", cpu)); 5.178 +} 5.179 + 5.180 +/* 5.181 + * debug dump_queue 5.182 + * arguments: queue head, name of queue 5.183 + */ 5.184 +static void dump_tqueue(struct list_head *queue, char *name) 5.185 +{ 5.186 + struct list_head *list; 5.187 + int loop = 0; 5.188 + struct ac_timer *t; 5.189 + 5.190 + printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue, 5.191 + (unsigned long) queue->next, (unsigned long) queue->prev); 5.192 + list_for_each (list, queue) { 5.193 + t = list_entry(list, struct ac_timer, timer_list); 5.194 + printk (" %s %d : %lx ex=0x%08X%08X %lu n: %lx, p: %lx\n", 5.195 + name, loop++, 5.196 + (unsigned long)list, 5.197 + (u32)(t->expires>>32), (u32)t->expires, t->data, 5.198 + (unsigned long)list->next, (unsigned long)list->prev); 5.199 + } 5.200 + return; 5.201 +} 5.202 + 5.203 + 5.204 +static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs) 5.205 +{ 5.206 + u_long flags; 5.207 + s_time_t now = NOW(); 5.208 + 5.209 + printk("Dumping ac_timer queues for cpu 0: NOW=0x%08X%08X\n", 5.210 + (u32)(now>>32), (u32)now); 5.211 + 5.212 + spin_lock_irqsave(&ac_timers[0].lock, flags); 5.213 + dump_tqueue(&ac_timers[0].timers, "ac_time"); 5.214 + spin_unlock_irqrestore(&ac_timers[0].lock, flags); 5.215 + printk("\n"); 5.216 + return; 5.217 } 5.218 5.219 /* 5.220 @@ -303,5 +362,6 @@ void __init ac_timer_init(void) 5.221 INIT_LIST_HEAD(&ac_timers[i].timers); 5.222 spin_lock_init(&ac_timers[i].lock); 5.223 } 5.224 - /* ac_timer_debug(0); */ 5.225 + 5.226 + add_key_handler('a', dump_timerq, "dump ac_timer queues"); 5.227 }
6.1 --- a/xen-2.4.16/common/schedule.c Fri Feb 14 13:18:19 2003 +0000 6.2 +++ b/xen-2.4.16/common/schedule.c Sat Feb 15 18:02:39 2003 +0000 6.3 @@ -282,6 +282,9 @@ asmlinkage void schedule(void) 6.4 return; 6.5 } 6.6 6.7 +/* 6.8 + * The scheduling timer. 6.9 + */ 6.10 static __cacheline_aligned int count[NR_CPUS]; 6.11 static void sched_timer(unsigned long foo) 6.12 { 6.13 @@ -290,14 +293,35 @@ static void sched_timer(unsigned long fo 6.14 s_time_t now; 6.15 int res; 6.16 6.17 + /* reschedule after each 5 ticks */ 6.18 if (count[cpu] >= 5) { 6.19 set_bit(_HYP_EVENT_NEED_RESCHED, &curr->hyp_events); 6.20 count[cpu] = 0; 6.21 - if (cpu == 0) 6.22 - update_time(); /* XXX RN: Should be moved on its own timer */ 6.23 } 6.24 count[cpu]++; 6.25 6.26 + /* 6.27 + * deliver virtual timer interrups to domains if we are CPU 0 6.28 + * XXX RN: We don't have a per CPU list of domains yet. Otherwise 6.29 + * would use that. Plus, this should be removed anyway once 6.30 + * Domains "know" about virtual time and timeouts. But, it's better 6.31 + * here then where it was before. 6.32 + */ 6.33 + if (cpu == 0) { 6.34 + struct task_struct *p; 6.35 + unsigned long cpu_mask = 0; 6.36 + 6.37 + /* send virtual timer interrupt */ 6.38 + read_lock(&tasklist_lock); 6.39 + p = &idle0_task; 6.40 + do { 6.41 + cpu_mask |= mark_guest_event(p, _EVENT_TIMER); 6.42 + } 6.43 + while ( (p = p->next_task) != &idle0_task ); 6.44 + read_unlock(&tasklist_lock); 6.45 + guest_event_notify(cpu_mask); 6.46 + } 6.47 + 6.48 again: 6.49 now = NOW(); 6.50 s_timer[cpu].expires = now + MILLISECS(10); 6.51 @@ -310,6 +334,8 @@ static void sched_timer(unsigned long fo 6.52 goto again; 6.53 6.54 } 6.55 + 6.56 + 6.57 /* 6.58 * Initialise the data structures 6.59 */
7.1 --- a/xen-2.4.16/common/timer.c Fri Feb 14 13:18:19 2003 +0000 7.2 +++ b/xen-2.4.16/common/timer.c Sat Feb 15 18:02:39 2003 +0000 7.3 @@ -586,27 +586,12 @@ void timer_bh(void) 7.4 7.5 void do_timer(struct pt_regs *regs) 7.6 { 7.7 - struct task_struct *p; 7.8 - shared_info_t *s; 7.9 - unsigned long cpu_mask = 0; 7.10 7.11 (*(unsigned long *)&jiffies)++; 7.12 7.13 if ( !using_apic_timer ) 7.14 update_process_times(user_mode(regs)); 7.15 7.16 - /* XXX RN: Move this for virtual domain time timer interrupts */ 7.17 - read_lock(&tasklist_lock); 7.18 - p = &idle0_task; 7.19 - do { 7.20 - s = p->shared_info; 7.21 - cpu_mask |= mark_guest_event(p, _EVENT_TIMER); 7.22 - } 7.23 - while ( (p = p->next_task) != &idle0_task ); 7.24 - read_unlock(&tasklist_lock); 7.25 - 7.26 - guest_event_notify(cpu_mask); 7.27 - 7.28 mark_bh(TIMER_BH); 7.29 if (TQ_ACTIVE(tq_timer)) 7.30 mark_bh(TQUEUE_BH);
8.1 --- a/xen-2.4.16/include/asm-i386/time.h Fri Feb 14 13:18:19 2003 +0000 8.2 +++ b/xen-2.4.16/include/asm-i386/time.h Sat Feb 15 18:02:39 2003 +0000 8.3 @@ -41,9 +41,6 @@ typedef s64 s_time_t; /* Syste 8.4 extern u32 stime_pcc; /* cycle counter value at last timer irq */ 8.5 extern s_time_t stime_now; /* time in ns at last timer IRQ */ 8.6 8.7 -/* update time variables once in a while */ 8.8 -extern void update_time(void); 8.9 - 8.10 /* 8.11 * Domain Virtual Time 8.12 */