debuggers.hg
changeset 974:464dff9c4e15
bitkeeper revision 1.596 (3fb247cfmIy4Y7E2SLnZRhjvUWmjXw)
schedule.c:
Fix a race when calling update_dom_time.
schedule.c:
Fix a race when calling update_dom_time.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Wed Nov 12 14:46:39 2003 +0000 (2003-11-12) |
parents | 87d895822ab8 |
children | eaaf88bbc222 cfd9961afd8b |
files | xen/common/schedule.c |
line diff
1.1 --- a/xen/common/schedule.c Wed Nov 12 13:22:54 2003 +0000 1.2 +++ b/xen/common/schedule.c Wed Nov 12 14:46:39 2003 +0000 1.3 @@ -53,9 +53,17 @@ typedef struct schedule_data_st 1.4 u32 hist[BUCKETS]; /* for scheduler latency histogram */ 1.5 #endif 1.6 } __cacheline_aligned schedule_data_t; 1.7 -schedule_data_t schedule_data[NR_CPUS]; 1.8 +static schedule_data_t schedule_data[NR_CPUS]; 1.9 + 1.10 +/* Skanky periodic event to all guests. This must die in the next release! */ 1.11 +static struct ac_timer v_timer; 1.12 1.13 -struct ac_timer v_timer; /* scheduling timer */ 1.14 +/* 1.15 + * Per-CPU timer to ensure that even guests with very long quantums get 1.16 + * their time-of-day state updated often enough to avoid wrapping. 1.17 + */ 1.18 +static struct ac_timer fallback_timer[NR_CPUS]; 1.19 + 1.20 static void virt_timer(unsigned long foo); 1.21 static void dump_rqueue(struct list_head *queue, char *name); 1.22 1.23 @@ -544,10 +552,8 @@ int idle_cpu(int cpu) 1.24 } 1.25 1.26 1.27 -/* 1.28 - * The scheduler timer. 1.29 - */ 1.30 -static void sched_timer(unsigned long foo) 1.31 +/* The scheduler timer. */ 1.32 +static void sched_timer(unsigned long unused) 1.33 { 1.34 int cpu = smp_processor_id(); 1.35 struct task_struct *curr = schedule_data[cpu].curr; 1.36 @@ -556,33 +562,42 @@ static void sched_timer(unsigned long fo 1.37 perfc_incrc(sched_irq); 1.38 } 1.39 1.40 -/* 1.41 - * The Domain virtual time timer 1.42 - */ 1.43 -static void virt_timer(unsigned long foo) 1.44 +/* The Domain virtual time timer */ 1.45 +static void virt_timer(unsigned long unused) 1.46 { 1.47 - unsigned long cpu_mask = 0; 1.48 + unsigned long flags, cpu_mask = 0; 1.49 struct task_struct *p; 1.50 s_time_t now; 1.51 1.52 /* send virtual timer interrupt */ 1.53 - read_lock(&tasklist_lock); 1.54 + read_lock_irqsave(&tasklist_lock, flags); 1.55 p = &idle0_task; 1.56 do { 1.57 if ( is_idle_task(p) ) continue; 1.58 cpu_mask |= mark_guest_event(p, _EVENT_TIMER); 1.59 - if ( p->has_cpu ) 1.60 - update_dom_time(p->shared_info); 1.61 } 1.62 while ( (p = p->next_task) != &idle0_task ); 1.63 - read_unlock(&tasklist_lock); 1.64 + read_unlock_irqrestore(&tasklist_lock, flags); 1.65 guest_event_notify(cpu_mask); 1.66 1.67 now = NOW(); 1.68 - v_timer.expires = now + MILLISECS(20); 1.69 + v_timer.expires = now + MILLISECS(20); 1.70 add_ac_timer(&v_timer); 1.71 } 1.72 1.73 +/* Fallback timer to ensure guests get time updated 'often enough'. */ 1.74 +static void fallback_timer_fn(unsigned long unused) 1.75 +{ 1.76 + struct task_struct *p = current; 1.77 + unsigned int cpu = p->processor; 1.78 + 1.79 + if ( !is_idle_task(p) ) 1.80 + update_dom_time(p->shared_info); 1.81 + 1.82 + fallback_timer[cpu].expires = NOW() + MILLISECS(500); 1.83 + add_ac_timer(&fallback_timer[cpu]); 1.84 +} 1.85 + 1.86 /* 1.87 * Initialise the data structures 1.88 */ 1.89 @@ -598,15 +613,19 @@ void __init scheduler_init(void) 1.90 spin_lock_init(&schedule_data[i].lock); 1.91 schedule_data[i].curr = &idle0_task; 1.92 1.93 - /* a timer for each CPU */ 1.94 init_ac_timer(&schedule_data[i].s_timer, i); 1.95 - schedule_data[i].s_timer.data = 2; 1.96 + schedule_data[i].s_timer.data = 2; 1.97 schedule_data[i].s_timer.function = &sched_timer; 1.98 1.99 + init_ac_timer(&fallback_timer[i], i); 1.100 + fallback_timer[i].data = 0; 1.101 + fallback_timer[i].function = &fallback_timer_fn; 1.102 } 1.103 - schedule_data[0].idle = &idle0_task; /* idle on CPU 0 is special */ 1.104 + 1.105 + schedule_data[0].idle = &idle0_task; 1.106 + 1.107 init_ac_timer(&v_timer, 0); 1.108 - v_timer.data = 3; 1.109 + v_timer.data = 0; 1.110 v_timer.function = &virt_timer; 1.111 } 1.112 1.113 @@ -617,9 +636,14 @@ void __init scheduler_init(void) 1.114 void schedulers_start(void) 1.115 { 1.116 printk("Start schedulers\n"); 1.117 - sched_timer(0); 1.118 + 1.119 virt_timer(0); 1.120 + 1.121 + sched_timer(0); 1.122 smp_call_function((void *)sched_timer, NULL, 1, 1); 1.123 + 1.124 + fallback_timer_fn(0); 1.125 + smp_call_function((void *)fallback_timer_fn, NULL, 1, 1); 1.126 } 1.127 1.128