diff options
author | Keir Fraser <keir@xen.org> | 2011-01-08 10:43:01 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-01-08 10:43:01 +0000 |
commit | f3af225db3f70df1c91cc70fea82ea67f6dffa8c (patch) | |
tree | d23fca31d132c28fc6ce75bd50ce201438faad52 /xen/common/timer.c | |
parent | d8ec7a2381c2b26ea518610fa95c507c6872bdfa (diff) | |
download | xen-f3af225db3f70df1c91cc70fea82ea67f6dffa8c.tar.gz xen-f3af225db3f70df1c91cc70fea82ea67f6dffa8c.tar.bz2 xen-f3af225db3f70df1c91cc70fea82ea67f6dffa8c.zip |
timer: Don't hardcode cpu0 in migrate_timers_from_cpu().
Although we don't allow cpu0 to be offlined, there's no need to
hardcode that assumption in the timer subsystem.
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common/timer.c')
-rw-r--r-- | xen/common/timer.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/xen/common/timer.c b/xen/common/timer.c index bbde897847..1e51ce3c58 100644 --- a/xen/common/timer.c +++ b/xen/common/timer.c @@ -546,39 +546,51 @@ static struct keyhandler dump_timerq_keyhandler = { .desc = "dump timer queues" }; -static void migrate_timers_from_cpu(unsigned int cpu) +static void migrate_timers_from_cpu(unsigned int old_cpu) { - struct timers *ts; + unsigned int new_cpu = first_cpu(cpu_online_map); + struct timers *old_ts, *new_ts; struct timer *t; bool_t notify = 0; - ASSERT((cpu != 0) && cpu_online(0)); + ASSERT(!cpu_online(old_cpu) && cpu_online(new_cpu)); - ts = &per_cpu(timers, cpu); + old_ts = &per_cpu(timers, old_cpu); + new_ts = &per_cpu(timers, new_cpu); - spin_lock_irq(&per_cpu(timers, 0).lock); - spin_lock(&ts->lock); + if ( old_cpu < new_cpu ) + { + spin_lock_irq(&old_ts->lock); + spin_lock(&new_ts->lock); + } + else + { + spin_lock_irq(&new_ts->lock); + spin_lock(&old_ts->lock); + } - while ( (t = GET_HEAP_SIZE(ts->heap) ? ts->heap[1] : ts->list) != NULL ) + while ( (t = GET_HEAP_SIZE(old_ts->heap) + ? old_ts->heap[1] : old_ts->list) != NULL ) { remove_entry(t); - atomic_write16(&t->cpu, 0); + atomic_write16(&t->cpu, new_cpu); notify |= add_entry(t); } - while ( !list_empty(&ts->inactive) ) + while ( !list_empty(&old_ts->inactive) ) { - t = list_entry(ts->inactive.next, struct timer, inactive); + t = list_entry(old_ts->inactive.next, struct timer, inactive); list_del(&t->inactive); - atomic_write16(&t->cpu, 0); - list_add(&t->inactive, &per_cpu(timers, 0).inactive); + atomic_write16(&t->cpu, new_cpu); + list_add(&t->inactive, &new_ts->inactive); } - spin_unlock(&ts->lock); - spin_unlock_irq(&per_cpu(timers, 0).lock); + spin_unlock(&old_ts->lock); + spin_unlock_irq(&new_ts->lock); + local_irq_enable(); if ( notify ) - cpu_raise_softirq(0, TIMER_SOFTIRQ); + cpu_raise_softirq(new_cpu, TIMER_SOFTIRQ); } static struct timer *dummy_heap; |