bitkeeper revision 1.596 (3fb247cfmIy4Y7E2SLnZRhjvUWmjXw)

schedule.c:
  Fix a race when calling update_dom_time.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2003-11-12 14:46:39 +00:00
1 parent 524264221e
commit f3d8a8e6c7
1 file changed
+45 -21
+45 -21
View File
@@ -53,9 +53,17 @@ typedef struct schedule_data_st
u32 hist[BUCKETS]; /* for scheduler latency histogram */
#endif
} __cacheline_aligned schedule_data_t;
schedule_data_t schedule_data[NR_CPUS];
static schedule_data_t schedule_data[NR_CPUS];
/* Skanky periodic event to all guests. This must die in the next release! */
static struct ac_timer v_timer;
/*
* Per-CPU timer to ensure that even guests with very long quantums get
* their time-of-day state updated often enough to avoid wrapping.
*/
static struct ac_timer fallback_timer[NR_CPUS];
struct ac_timer v_timer; /* scheduling timer */
static void virt_timer(unsigned long foo);
static void dump_rqueue(struct list_head *queue, char *name);
@@ -544,10 +552,8 @@ int idle_cpu(int cpu)
}
/*
* The scheduler timer.
*/
static void sched_timer(unsigned long foo)
/* The scheduler timer. */
static void sched_timer(unsigned long unused)
{
int cpu = smp_processor_id();
struct task_struct *curr = schedule_data[cpu].curr;
@@ -556,33 +562,42 @@ static void sched_timer(unsigned long foo)
perfc_incrc(sched_irq);
}
/*
* The Domain virtual time timer
*/
static void virt_timer(unsigned long foo)
/* The Domain virtual time timer */
static void virt_timer(unsigned long unused)
{
unsigned long cpu_mask = 0;
unsigned long flags, cpu_mask = 0;
struct task_struct *p;
s_time_t now;
/* send virtual timer interrupt */
read_lock(&tasklist_lock);
read_lock_irqsave(&tasklist_lock, flags);
p = &idle0_task;
do {
if ( is_idle_task(p) ) continue;
cpu_mask |= mark_guest_event(p, _EVENT_TIMER);
if ( p->has_cpu )
update_dom_time(p->shared_info);
}
while ( (p = p->next_task) != &idle0_task );
read_unlock(&tasklist_lock);
read_unlock_irqrestore(&tasklist_lock, flags);
guest_event_notify(cpu_mask);
now = NOW();
v_timer.expires = now + MILLISECS(20);
v_timer.expires = now + MILLISECS(20);
add_ac_timer(&v_timer);
}
/* Fallback timer to ensure guests get time updated 'often enough'. */
static void fallback_timer_fn(unsigned long unused)
{
struct task_struct *p = current;
unsigned int cpu = p->processor;
if ( !is_idle_task(p) )
update_dom_time(p->shared_info);
fallback_timer[cpu].expires = NOW() + MILLISECS(500);
add_ac_timer(&fallback_timer[cpu]);
}
/*
* Initialise the data structures
*/
@@ -598,15 +613,19 @@ void __init scheduler_init(void)
spin_lock_init(&schedule_data[i].lock);
schedule_data[i].curr = &idle0_task;
/* a timer for each CPU */
init_ac_timer(&schedule_data[i].s_timer, i);
schedule_data[i].s_timer.data = 2;
schedule_data[i].s_timer.data = 2;
schedule_data[i].s_timer.function = &sched_timer;
init_ac_timer(&fallback_timer[i], i);
fallback_timer[i].data = 0;
fallback_timer[i].function = &fallback_timer_fn;
}
schedule_data[0].idle = &idle0_task; /* idle on CPU 0 is special */
schedule_data[0].idle = &idle0_task;
init_ac_timer(&v_timer, 0);
v_timer.data = 3;
v_timer.data = 0;
v_timer.function = &virt_timer;
}
@@ -617,9 +636,14 @@ void __init scheduler_init(void)
void schedulers_start(void)
{
printk("Start schedulers\n");
sched_timer(0);
virt_timer(0);
sched_timer(0);
smp_call_function((void *)sched_timer, NULL, 1, 1);
fallback_timer_fn(0);
smp_call_function((void *)fallback_timer_fn, NULL, 1, 1);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.