direct-io.hg
changeset 230:a9994f1785cb
bitkeeper revision 1.88 (3e564e1cTiVK2rPAdHl9ccMD8nraEw)
ac_timer.c, apic.c:
Fix timer code to schedule alarm handlers with some slop.
ac_timer.c, apic.c:
Fix timer code to schedule alarm handlers with some slop.
author | kaf24@labyrinth.cl.cam.ac.uk |
---|---|
date | Fri Feb 21 16:04:44 2003 +0000 (2003-02-21) |
parents | fa6d46f14a6e |
children | 5262380c8422 |
files | xen-2.4.16/arch/i386/apic.c xen-2.4.16/common/ac_timer.c |
line diff
1.1 --- a/xen-2.4.16/arch/i386/apic.c Fri Feb 21 15:30:00 2003 +0000 1.2 +++ b/xen-2.4.16/arch/i386/apic.c Fri Feb 21 16:04:44 2003 +0000 1.3 @@ -218,9 +218,7 @@ int __init verify_local_APIC(void) 1.4 1.5 void __init sync_Arb_IDs(void) 1.6 { 1.7 - /* 1.8 - * Wait for idle. 1.9 - */ 1.10 + /* Wait for idle. */ 1.11 apic_wait_icr_idle(); 1.12 1.13 Dprintk("Synchronizing Arb IDs.\n"); 1.14 @@ -508,11 +506,11 @@ void __init wait_8254_wraparound(void) 1.15 prev_count = curr_count; 1.16 curr_count = get_8254_timer_count(); 1.17 delta = curr_count-prev_count; 1.18 - /* 1.19 - * This limit for delta seems arbitrary, but it isn't, it's 1.20 - * slightly above the level of error a buggy Mercury/Neptune 1.21 - * chipset timer can cause. 1.22 - */ 1.23 + /* 1.24 + * This limit for delta seems arbitrary, but it isn't, it's slightly 1.25 + * above the level of error a buggy Mercury/Neptune chipset timer can 1.26 + * cause. 1.27 + */ 1.28 } while (delta < 300); 1.29 } 1.30 1.31 @@ -581,7 +579,7 @@ int __init calibrate_APIC_clock(void) 1.32 * counter running for calibration. */ 1.33 __setup_APIC_LVTT(1000000000); 1.34 1.35 - /* The timer chip counts down to zero. Let's wait 1.36 + /* The timer chip counts down to zero. Let's wait 1.37 * for a wraparound to start exact measurement: 1.38 * (the current tick might have been already half done) */ 1.39 wait_8254_wraparound(); 1.40 @@ -611,18 +609,18 @@ int __init calibrate_APIC_clock(void) 1.41 result/(1000000/HZ), 1.42 result%(1000000/HZ)); 1.43 1.44 - cpu_freq = (u64)(((t2-t1)/LOOPS)*HZ); 1.45 + cpu_freq = (u64)(((t2-t1)/LOOPS)*HZ); 1.46 1.47 - /* set up multipliers for accurate timer code */ 1.48 - bus_freq = result*HZ; 1.49 - bus_cycle = (u32) (1000000000000LL/bus_freq); /* in pico seconds */ 1.50 - bus_scale = (1000*262144)/bus_cycle; 1.51 + /* set up multipliers for accurate timer code */ 1.52 + bus_freq = result*HZ; 1.53 + bus_cycle = (u32) (1000000000000LL/bus_freq); /* in pico seconds */ 1.54 + bus_scale = (1000*262144)/bus_cycle; 1.55 1.56 - /* print results */ 1.57 - printk("..... bus_freq = %u Hz\n", bus_freq); 1.58 - printk("..... bus_cycle = %u ps\n", bus_cycle); 1.59 - printk("..... bus_scale = %u \n", bus_scale); 1.60 - /* reset APIC to zero timeout value */ 1.61 + /* print results */ 1.62 + printk("..... bus_freq = %u Hz\n", bus_freq); 1.63 + printk("..... bus_cycle = %u ps\n", bus_cycle); 1.64 + printk("..... bus_scale = %u \n", bus_scale); 1.65 + /* reset APIC to zero timeout value */ 1.66 __setup_APIC_LVTT(0); 1.67 return result; 1.68 } 1.69 @@ -636,7 +634,7 @@ void __init setup_APIC_clocks (void) 1.70 printk("Using local APIC timer interrupts.\n"); 1.71 using_apic_timer = 1; 1.72 __cli(); 1.73 - /* calibrate CPU0 for CPU speed and BUS speed */ 1.74 + /* calibrate CPU0 for CPU speed and BUS speed */ 1.75 bus_freq = calibrate_APIC_clock(); 1.76 /* Now set up the timer for real. */ 1.77 setup_APIC_timer((void *)bus_freq); 1.78 @@ -654,41 +652,38 @@ void __init setup_APIC_clocks (void) 1.79 */ 1.80 int reprogram_ac_timer(s_time_t timeout) 1.81 { 1.82 - int cpu = smp_processor_id(); 1.83 - s_time_t now; 1.84 - s_time_t expire; 1.85 - u64 apic_tmict; 1.86 - 1.87 - now = NOW(); 1.88 - expire = timeout - now; /* value from now */ 1.89 + int cpu = smp_processor_id(); 1.90 + s_time_t now; 1.91 + s_time_t expire; 1.92 + u64 apic_tmict; 1.93 1.94 + now = NOW(); 1.95 + expire = timeout - now; /* value from now */ 1.96 1.97 - if (expire <= 0) { 1.98 - TRC(printk("APICT[%02d] Timeout in the past 0x%08X%08X > 0x%08X%08X\n", 1.99 - cpu, (u32)(now>>32), (u32)now, 1.100 - (u32)(timeout>>32),(u32)timeout)); 1.101 - return 0; /* timeout value in the past */ 1.102 - } 1.103 + if (expire <= 0) { 1.104 + printk("APICT[%02d] Timeout in the past 0x%08X%08X > 0x%08X%08X\n", 1.105 + cpu, (u32)(now>>32), (u32)now, (u32)(timeout>>32),(u32)timeout); 1.106 + return 0; /* timeout value in the past */ 1.107 + } 1.108 1.109 - /* conversion to bus units */ 1.110 - apic_tmict = (((u64)bus_scale) * expire)>>18; 1.111 + /* conversion to bus units */ 1.112 + apic_tmict = (((u64)bus_scale) * expire)>>18; 1.113 1.114 - if (apic_tmict >= 0xffffffff) { 1.115 - /* This is bad! */ 1.116 - printk("APICT[%02d] Timeout value too large\n", cpu); 1.117 - apic_tmict = 0xffffffff; 1.118 - } 1.119 - if (apic_tmict == 0) { 1.120 - TRC(printk("APICT[%02d] timeout value too small\n", cpu)); 1.121 - return 0; 1.122 - } 1.123 + if (apic_tmict >= 0xffffffff) { 1.124 + printk("APICT[%02d] Timeout value too large\n", cpu); 1.125 + apic_tmict = 0xffffffff; 1.126 + } 1.127 + if (apic_tmict == 0) { 1.128 + printk("APICT[%02d] timeout value too small\n", cpu); 1.129 + return 0; 1.130 + } 1.131 1.132 - /* programm timer */ 1.133 - apic_write(APIC_TMICT, (unsigned long)apic_tmict); 1.134 + /* programm timer */ 1.135 + apic_write(APIC_TMICT, (unsigned long)apic_tmict); 1.136 1.137 - TRC(printk("APICT[%02d] reprog(): expire=%lld %u\n", 1.138 - cpu, expire, apic_tmict)); 1.139 - return 1; 1.140 + TRC(printk("APICT[%02d] reprog(): expire=%lld %u\n", 1.141 + cpu, expire, apic_tmict)); 1.142 + return 1; 1.143 } 1.144 1.145 /* 1.146 @@ -702,29 +697,28 @@ int reprogram_ac_timer(s_time_t timeout) 1.147 static s_time_t last_cpu0_tirq = 0; 1.148 inline void smp_local_timer_interrupt(struct pt_regs * regs) 1.149 { 1.150 - int cpu = smp_processor_id(); 1.151 - s_time_t diff, now; 1.152 - 1.153 + int cpu = smp_processor_id(); 1.154 + s_time_t diff, now; 1.155 1.156 /* if CPU 0 do old timer stuff */ 1.157 - if (cpu == 0) { 1.158 - 1.159 - now = NOW(); 1.160 - diff = now - last_cpu0_tirq; 1.161 + if (cpu == 0) 1.162 + { 1.163 + now = NOW(); 1.164 + diff = now - last_cpu0_tirq; 1.165 1.166 - if (diff <= 0) { 1.167 - printk ("System Time went backwards: %lld\n", diff); 1.168 - return; 1.169 - } 1.170 + if (diff <= 0) { 1.171 + printk ("System Time went backwards: %lld\n", diff); 1.172 + return; 1.173 + } 1.174 1.175 - while (diff >= MILLISECS(10)) { 1.176 - do_timer(regs); 1.177 - diff -= MILLISECS(10); 1.178 - last_cpu0_tirq += MILLISECS(10); 1.179 - } 1.180 - } 1.181 - /* call accurate timer function */ 1.182 - do_ac_timer(); 1.183 + while (diff >= MILLISECS(10)) { 1.184 + do_timer(regs); 1.185 + diff -= MILLISECS(10); 1.186 + last_cpu0_tirq += MILLISECS(10); 1.187 + } 1.188 + } 1.189 + /* call accurate timer function */ 1.190 + do_ac_timer(); 1.191 } 1.192 1.193 /* 1.194 @@ -747,9 +741,8 @@ void smp_apic_timer_interrupt(struct pt_ 1.195 apic_timer_irqs[cpu]++; 1.196 1.197 /* 1.198 - * NOTE! We'd better ACK the irq immediately, 1.199 - * because timer handling can be slow. 1.200 - * XXX is this save? 1.201 + * NOTE! We'd better ACK the irq immediately, because timer handling can 1.202 + * be slow. XXX is this save? 1.203 */ 1.204 ack_APIC_irq(); 1.205 1.206 @@ -825,7 +818,7 @@ int __init APIC_init_uniprocessor (void) 1.207 * Complain if the BIOS pretends there is one. 1.208 */ 1.209 if (!cpu_has_apic&&APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) 1.210 - { 1.211 + { 1.212 printk("BIOS bug, local APIC #%d not detected!...\n", 1.213 boot_cpu_physical_apicid); 1.214 return -1;
2.1 --- a/xen-2.4.16/common/ac_timer.c Fri Feb 21 15:30:00 2003 +0000 2.2 +++ b/xen-2.4.16/common/ac_timer.c Fri Feb 21 16:04:44 2003 +0000 2.3 @@ -44,6 +44,12 @@ 2.4 #define TRC(_x) 2.5 #endif 2.6 2.7 +/* 2.8 + * We pull handlers off the timer list this far in future, 2.9 + * rather than reprogramming the time hardware. 2.10 + */ 2.11 +#define TIMER_SLOP (50*1000) /* ns */ 2.12 + 2.13 /* A timer list per CPU */ 2.14 typedef struct ac_timers_st 2.15 { 2.16 @@ -58,8 +64,8 @@ static ac_timers_t ac_timers[NR_CPUS]; 2.17 #define MAX_STATS 2.18 typedef struct act_stats_st 2.19 { 2.20 - u32 count; 2.21 - u32 times[2*(BUCKETS)]; 2.22 + u32 count; 2.23 + u32 times[2*(BUCKETS)]; 2.24 } __cacheline_aligned act_stats_t; 2.25 static act_stats_t act_stats[NR_CPUS]; 2.26 2.27 @@ -79,71 +85,68 @@ static int detach_ac_timer(struct ac_ti 2.28 */ 2.29 int add_ac_timer(struct ac_timer *timer) 2.30 { 2.31 - int cpu = smp_processor_id(); 2.32 - unsigned long flags; 2.33 - s_time_t now; 2.34 - 2.35 - /* sanity checks */ 2.36 + int cpu = smp_processor_id(); 2.37 + unsigned long flags; 2.38 + s_time_t now; 2.39 2.40 - /* make sure timeout value is in the future */ 2.41 - now = NOW(); 2.42 - TRC(printk("ACT [%02d] add(): now=%lld timo=%lld\n", 2.43 - cpu, now, timer->expires)); 2.44 - if (timer->expires <= now) { 2.45 - printk("ACT[%02d] add_ac_timer: now=0x%08X%08X > expire=0x%08X%08X\n", 2.46 - cpu, (u32)(now>>32), (u32)now, 2.47 - (u32)(timer->expires>>32), (u32)timer->expires); 2.48 - return 1; 2.49 - } 2.50 - spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.51 - /* 2.52 + /* make sure timeout value is in the future */ 2.53 + now = NOW(); 2.54 + TRC(printk("ACT [%02d] add(): now=%lld timo=%lld\n", 2.55 + cpu, now, timer->expires)); 2.56 + if (timer->expires <= now) { 2.57 + printk("ACT[%02d] add_ac_timer: now=0x%08X%08X > expire=0x%08X%08X\n", 2.58 + cpu, (u32)(now>>32), (u32)now, 2.59 + (u32)(timer->expires>>32), (u32)timer->expires); 2.60 + return 1; 2.61 + } 2.62 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.63 + /* 2.64 * Add timer to the list. If it gets added to the front we have to 2.65 * reprogramm the timer 2.66 */ 2.67 - if (list_empty(&ac_timers[cpu].timers)) { 2.68 - /* Reprogramm and add to head of list */ 2.69 - if (!reprogram_ac_timer(timer->expires)) { 2.70 - /* failed */ 2.71 - printk("ACT [%02d] add(): add at head failed\n", cpu); 2.72 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.73 - return 1; 2.74 - } 2.75 - list_add(&timer->timer_list, &ac_timers[cpu].timers); 2.76 - TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 2.77 - (u32)(timer->expires>>32), (u32)timer->expires)); 2.78 - } else { 2.79 - struct list_head *pos; 2.80 - struct ac_timer *t; 2.81 - for (pos = ac_timers[cpu].timers.next; 2.82 - pos != &ac_timers[cpu].timers; 2.83 - pos = pos->next) { 2.84 - t = list_entry(pos, struct ac_timer, timer_list); 2.85 - if (t->expires > timer->expires) 2.86 - break; 2.87 - } 2.88 + if (list_empty(&ac_timers[cpu].timers)) { 2.89 + /* Reprogramm and add to head of list */ 2.90 + if (!reprogram_ac_timer(timer->expires)) { 2.91 + /* failed */ 2.92 + printk("ACT [%02d] add(): add at head failed\n", cpu); 2.93 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.94 + return 1; 2.95 + } 2.96 + list_add(&timer->timer_list, &ac_timers[cpu].timers); 2.97 + TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 2.98 + (u32)(timer->expires>>32), (u32)timer->expires)); 2.99 + } else { 2.100 + struct list_head *pos; 2.101 + struct ac_timer *t; 2.102 + for (pos = ac_timers[cpu].timers.next; 2.103 + pos != &ac_timers[cpu].timers; 2.104 + pos = pos->next) { 2.105 + t = list_entry(pos, struct ac_timer, timer_list); 2.106 + if (t->expires > timer->expires) 2.107 + break; 2.108 + } 2.109 2.110 - if (pos->prev == &ac_timers[cpu].timers) { 2.111 - /* added to head, reprogramm timer */ 2.112 - if (!reprogram_ac_timer(timer->expires)) { 2.113 - /* failed */ 2.114 - TRC(printk("ACT [%02d] add(): add at head failed\n", cpu)); 2.115 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.116 - return 1; 2.117 - } 2.118 - list_add (&(timer->timer_list), pos->prev); 2.119 - TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 2.120 - (u32)(timer->expires>>32), (u32)timer->expires)); 2.121 - } else { 2.122 - list_add (&(timer->timer_list), pos->prev); 2.123 - TRC(printk("ACT [%02d] add(0x%08X%08X): add < exp=0x%08X%08X\n", 2.124 - cpu, 2.125 - (u32)(timer->expires>>32), (u32)timer->expires, 2.126 - (u32)(t->expires>>32), (u32)t->expires)); 2.127 - } 2.128 - 2.129 - } 2.130 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.131 - return 0; 2.132 + if (pos->prev == &ac_timers[cpu].timers) { 2.133 + /* added to head, reprogramm timer */ 2.134 + if (!reprogram_ac_timer(timer->expires)) { 2.135 + /* failed */ 2.136 + TRC(printk("ACT [%02d] add(): add at head failed\n", cpu)); 2.137 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.138 + return 1; 2.139 + } 2.140 + list_add (&(timer->timer_list), pos->prev); 2.141 + TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu, 2.142 + (u32)(timer->expires>>32), (u32)timer->expires)); 2.143 + } else { 2.144 + list_add (&(timer->timer_list), pos->prev); 2.145 + TRC(printk("ACT [%02d] add(0x%08X%08X): add < exp=0x%08X%08X\n", 2.146 + cpu, 2.147 + (u32)(timer->expires>>32), (u32)timer->expires, 2.148 + (u32)(t->expires>>32), (u32)t->expires)); 2.149 + } 2.150 + } 2.151 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.152 + return 0; 2.153 } 2.154 2.155 /* 2.156 @@ -154,11 +157,11 @@ int add_ac_timer(struct ac_timer *timer) 2.157 */ 2.158 static int detach_ac_timer(struct ac_timer *timer) 2.159 { 2.160 - TRC(int cpu = smp_processor_id()); 2.161 - TRC(printk("ACT [%02d] detach(): \n", cpu)); 2.162 - list_del(&timer->timer_list); 2.163 - timer->timer_list.next = NULL; 2.164 - return 0; 2.165 + TRC(int cpu = smp_processor_id()); 2.166 + TRC(printk("ACT [%02d] detach(): \n", cpu)); 2.167 + list_del(&timer->timer_list); 2.168 + timer->timer_list.next = NULL; 2.169 + return 0; 2.170 } 2.171 2.172 /* 2.173 @@ -169,18 +172,17 @@ static int detach_ac_timer(struct ac_tim 2.174 */ 2.175 int rem_ac_timer(struct ac_timer *timer) 2.176 { 2.177 - int cpu = smp_processor_id(); 2.178 - int res; 2.179 - unsigned long flags; 2.180 + int cpu = smp_processor_id(); 2.181 + int res; 2.182 + unsigned long flags; 2.183 + 2.184 + TRC(printk("ACT [%02d] remove(): timo=%lld \n", cpu, timer->expires)); 2.185 2.186 - TRC(printk("ACT [%02d] remove(): timo=%lld \n", cpu, timer->expires)); 2.187 - /* sanity checks */ 2.188 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.189 + res = detach_ac_timer(timer); 2.190 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.191 2.192 - spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.193 - res = detach_ac_timer(timer); 2.194 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.195 - 2.196 - return res; 2.197 + return res; 2.198 } 2.199 2.200 /* 2.201 @@ -191,12 +193,12 @@ int rem_ac_timer(struct ac_timer *timer) 2.202 */ 2.203 int mod_ac_timer(struct ac_timer *timer, s_time_t new_time) 2.204 { 2.205 - if (rem_ac_timer(timer) != 0) 2.206 - return -1; 2.207 - timer->expires = new_time; 2.208 - if (add_ac_timer(timer) != 0) 2.209 - return -1; 2.210 - return 0; 2.211 + if (rem_ac_timer(timer) != 0) 2.212 + return -1; 2.213 + timer->expires = new_time; 2.214 + if (add_ac_timer(timer) != 0) 2.215 + return -1; 2.216 + return 0; 2.217 } 2.218 2.219 /* 2.220 @@ -205,108 +207,76 @@ int mod_ac_timer(struct ac_timer *timer, 2.221 */ 2.222 void do_ac_timer(void) 2.223 { 2.224 - int cpu = smp_processor_id(); 2.225 - unsigned long flags; 2.226 - s_time_t now; 2.227 - struct ac_timer *t; 2.228 - struct list_head *tmp; 2.229 + int cpu = smp_processor_id(); 2.230 + unsigned long flags; 2.231 + struct ac_timer *t; 2.232 2.233 - spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.234 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.235 2.236 do_timer_again: 2.237 2.238 - now = NOW(); 2.239 - TRC(printk("ACT [%02d] do(): now=%lld\n", cpu, now)); 2.240 + TRC(printk("ACT [%02d] do(): now=%lld\n", cpu, NOW())); 2.241 2.242 - /* Sanity checks */ 2.243 - /* empty time list */ 2.244 - if (list_empty(&ac_timers[cpu].timers)) { 2.245 - printk("ACT[%02d] do_ac_timer(): timer irq without timer\n", cpu); 2.246 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.247 - return; 2.248 - } 2.249 - 2.250 - 2.251 - /* execute the head of timer queue */ 2.252 - t = list_entry(ac_timers[cpu].timers.next, struct ac_timer, timer_list); 2.253 - detach_ac_timer(t); 2.254 - 2.255 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.256 - 2.257 + /* Sanity: is the timer list empty? */ 2.258 + if ( list_empty(&ac_timers[cpu].timers) ) 2.259 + printk("ACT[%02d] do_ac_timer(): timer irq without timer\n", cpu); 2.260 2.261 #ifdef AC_TIMER_STATS 2.262 - { 2.263 - s32 diff; 2.264 - u32 i; 2.265 - diff = ((s32)(now - t->expires)) / 1000; /* delta in us */ 2.266 - if (diff < -BUCKETS) 2.267 - diff = -BUCKETS; 2.268 - else if (diff > BUCKETS) 2.269 - diff = BUCKETS; 2.270 - act_stats[cpu].times[diff+BUCKETS]++; 2.271 - act_stats[cpu].count++; 2.272 + { 2.273 + s32 diff; 2.274 + u32 i; 2.275 + diff = ((s32)(NOW() - t->expires)) / 1000; /* delta in us */ 2.276 + if (diff < -BUCKETS) 2.277 + diff = -BUCKETS; 2.278 + else if (diff > BUCKETS) 2.279 + diff = BUCKETS; 2.280 + act_stats[cpu].times[diff+BUCKETS]++; 2.281 + act_stats[cpu].count++; 2.282 2.283 - if (act_stats[cpu].count >= 5000) { 2.284 - printk("ACT Stats\n"); 2.285 + if (act_stats[cpu].count >= 5000) { 2.286 + printk("ACT Stats\n"); 2.287 for (i=0; i < 2*BUCKETS; i++) { 2.288 if (act_stats[cpu].times[i] != 0) 2.289 - printk("ACT [%02d]: %3dus: %5d\n", 2.290 - cpu,i-BUCKETS, act_stats[cpu].times[i]); 2.291 - act_stats[cpu].times[i]=0; 2.292 - } 2.293 - act_stats[cpu].count = 0; 2.294 - printk("\n"); 2.295 - } 2.296 - } 2.297 + printk("ACT [%02d]: %3dus: %5d\n", 2.298 + cpu,i-BUCKETS, act_stats[cpu].times[i]); 2.299 + act_stats[cpu].times[i]=0; 2.300 + } 2.301 + act_stats[cpu].count = 0; 2.302 + printk("\n"); 2.303 + } 2.304 + } 2.305 #endif 2.306 2.307 - 2.308 - 2.309 - if (t->expires > now) { 2.310 - //printk("ACT [%02d] do(): irq too early (%lld ns)\n", 2.311 - // cpu, now - t->expires ); 2.312 - } 2.313 - if (t->function != NULL) 2.314 - t->function(t->data); 2.315 - 2.316 - 2.317 - /* check if there are other timer functions on the list */ 2.318 - now = NOW(); 2.319 - 2.320 - spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.321 + /* Handle all timeouts in the near future. */ 2.322 + while ( !list_empty(&ac_timers[cpu].timers) ) 2.323 + { 2.324 + t = list_entry(ac_timers[cpu].timers.next, 2.325 + struct ac_timer, timer_list); 2.326 + if ( t->expires > (NOW() + TIMER_SLOP) ) break; 2.327 + detach_ac_timer(t); 2.328 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.329 + if ( t->function != NULL ) t->function(t->data); 2.330 + spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.331 + } 2.332 + 2.333 + /* If list not empty then reprogram timer to new head of list */ 2.334 + if ( !list_empty(&ac_timers[cpu].timers) ) 2.335 + { 2.336 + t = list_entry(ac_timers[cpu].timers.next, 2.337 + struct ac_timer, timer_list); 2.338 + if ( t->expires > 0 ) 2.339 + { 2.340 + TRC(printk("ACT [%02d] do(): reprog timo=%lld\n",cpu,t->expires)); 2.341 + if ( !reprogram_ac_timer(t->expires) ) 2.342 + { 2.343 + TRC(printk("ACT [%02d] do(): again\n", cpu)); 2.344 + goto do_timer_again; 2.345 + } 2.346 + } 2.347 + } 2.348 2.349 - if (!list_empty(&ac_timers[cpu].timers)) { 2.350 - list_for_each(tmp, &ac_timers[cpu].timers) { 2.351 - t = list_entry(tmp, struct ac_timer, timer_list); 2.352 - TRC(printk("ACT [%02d] do(): now=%lld timo=%lld\n", 2.353 - cpu, now, t->expires)); 2.354 - if (t->expires <= now) { 2.355 - detach_ac_timer(t); 2.356 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.357 - if (t->function != NULL) 2.358 - t->function(t->data); 2.359 - spin_lock_irqsave(&ac_timers[cpu].lock, flags); 2.360 - now = NOW(); 2.361 - } else { 2.362 - TRC(printk("ACT [%02d] do(): break1\n", cpu)); 2.363 - break; 2.364 - } 2.365 - } 2.366 - } 2.367 - 2.368 - /* If list not empty reprogramm timer to new head of list */ 2.369 - if (!list_empty(&ac_timers[cpu].timers)) { 2.370 - t = list_entry(ac_timers[cpu].timers.next,struct ac_timer,timer_list); 2.371 - if (t->expires > 0) { 2.372 - TRC(printk("ACT [%02d] do(): reprog timo=%lld\n",cpu,t->expires)); 2.373 - if (!reprogram_ac_timer(t->expires)) { 2.374 - TRC(printk("ACT [%02d] do(): again\n", cpu)); 2.375 - goto do_timer_again; 2.376 - } 2.377 - } 2.378 - } 2.379 - spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.380 - TRC(printk("ACT [%02d] do(): end\n", cpu)); 2.381 + spin_unlock_irqrestore(&ac_timers[cpu].lock, flags); 2.382 + TRC(printk("ACT [%02d] do(): end\n", cpu)); 2.383 } 2.384 2.385 /* 2.386 @@ -317,16 +287,16 @@ static void dump_tqueue(struct list_head 2.387 { 2.388 struct list_head *list; 2.389 int loop = 0; 2.390 - struct ac_timer *t; 2.391 + struct ac_timer *t; 2.392 2.393 printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue, 2.394 (unsigned long) queue->next, (unsigned long) queue->prev); 2.395 list_for_each (list, queue) { 2.396 - t = list_entry(list, struct ac_timer, timer_list); 2.397 + t = list_entry(list, struct ac_timer, timer_list); 2.398 printk (" %s %d : %lx ex=0x%08X%08X %lu n: %lx, p: %lx\n", 2.399 - name, loop++, 2.400 + name, loop++, 2.401 (unsigned long)list, 2.402 - (u32)(t->expires>>32), (u32)t->expires, t->data, 2.403 + (u32)(t->expires>>32), (u32)t->expires, t->data, 2.404 (unsigned long)list->next, (unsigned long)list->prev); 2.405 } 2.406 return; 2.407 @@ -336,32 +306,30 @@ static void dump_tqueue(struct list_head 2.408 static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs) 2.409 { 2.410 u_long flags; 2.411 - s_time_t now = NOW(); 2.412 + s_time_t now = NOW(); 2.413 2.414 printk("Dumping ac_timer queues for cpu 0: NOW=0x%08X%08X\n", 2.415 - (u32)(now>>32), (u32)now); 2.416 + (u32)(now>>32), (u32)now); 2.417 2.418 spin_lock_irqsave(&ac_timers[0].lock, flags); 2.419 dump_tqueue(&ac_timers[0].timers, "ac_time"); 2.420 spin_unlock_irqrestore(&ac_timers[0].lock, flags); 2.421 - printk("\n"); 2.422 + printk("\n"); 2.423 return; 2.424 } 2.425 2.426 -/* 2.427 - * init 2.428 - */ 2.429 + 2.430 void __init ac_timer_init(void) 2.431 { 2.432 int i; 2.433 2.434 - printk ("ACT: Initialising Accurate timers\n"); 2.435 + printk ("ACT: Initialising Accurate timers\n"); 2.436 2.437 for (i = 0; i < NR_CPUS; i++) 2.438 { 2.439 - INIT_LIST_HEAD(&ac_timers[i].timers); 2.440 - spin_lock_init(&ac_timers[i].lock); 2.441 + INIT_LIST_HEAD(&ac_timers[i].timers); 2.442 + spin_lock_init(&ac_timers[i].lock); 2.443 } 2.444 2.445 - add_key_handler('a', dump_timerq, "dump ac_timer queues"); 2.446 + add_key_handler('a', dump_timerq, "dump ac_timer queues"); 2.447 }