Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
xen
23096-x86-hpet-no-cpumask_lock.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 23096-x86-hpet-no-cpumask_lock.patch of Package xen
# HG changeset patch # User Jan Beulich <jbeulich@novell.com> # Date 1301043797 0 # Node ID a65612bcbb921e98a8843157bf365e4ab16e8144 # Parent 941119d58655f2b2df86d9ecc4cb502bbc5e783c x86/hpet: eliminate cpumask_lock According to the (now getting removed) comment in struct hpet_event_channel, this was to prevent accessing a CPU's timer_deadline after it got cleared from cpumask. This can be done without a lock altogether - hpet_broadcast_exit() can simply clear the bit, and handle_hpet_broadcast() can read timer_deadline before looking at the mask a second time (the cpumask bit was already found set by the surrounding loop). Signed-off-by: Jan Beulich <jbeulich@novell.com> Acked-by: Gang Wei <gang.wei@intel.com> Index: xen-4.1.2-testing/xen/arch/x86/hpet.c =================================================================== --- xen-4.1.2-testing.orig/xen/arch/x86/hpet.c +++ xen-4.1.2-testing/xen/arch/x86/hpet.c @@ -34,18 +34,6 @@ struct hpet_event_channel int shift; s_time_t next_event; cpumask_t cpumask; - /* - * cpumask_lock is used to prevent hpet intr handler from accessing other - * cpu's timer_deadline after the other cpu's mask was cleared -- - * mask cleared means cpu waken up, then accessing timer_deadline from - * other cpu is not safe. - * It is not used for protecting cpumask, so set ops needn't take it. - * Multiple cpus clear cpumask simultaneously is ok due to the atomic - * feature of cpu_clear, so hpet_broadcast_exit() can take read lock for - * clearing cpumask, and handle_hpet_broadcast() have to take write lock - * for read cpumask & access timer_deadline. - */ - rwlock_t cpumask_lock; spinlock_t lock; void (*event_handler)(struct hpet_event_channel *); @@ -208,17 +196,18 @@ again: /* find all expired events */ for_each_cpu_mask(cpu, ch->cpumask) { - write_lock_irq(&ch->cpumask_lock); + s_time_t deadline; - if ( cpu_isset(cpu, ch->cpumask) ) - { - if ( per_cpu(timer_deadline, cpu) <= now ) - cpu_set(cpu, mask); - else if ( per_cpu(timer_deadline, cpu) < next_event ) - next_event = per_cpu(timer_deadline, cpu); - } + rmb(); + deadline = per_cpu(timer_deadline, cpu); + rmb(); + if ( !cpu_isset(cpu, ch->cpumask) ) + continue; - write_unlock_irq(&ch->cpumask_lock); + if ( deadline <= now ) + cpu_set(cpu, mask); + else if ( deadline < next_event ) + next_event = deadline; } /* wakeup the cpus which have an expired event. */ @@ -598,7 +587,6 @@ void hpet_broadcast_init(void) hpet_events[i].shift = 32; hpet_events[i].next_event = STIME_MAX; spin_lock_init(&hpet_events[i].lock); - rwlock_init(&hpet_events[i].cpumask_lock); wmb(); hpet_events[i].event_handler = handle_hpet_broadcast; } @@ -634,7 +622,6 @@ void hpet_broadcast_init(void) legacy_hpet_event.idx = 0; legacy_hpet_event.flags = 0; spin_lock_init(&legacy_hpet_event.lock); - rwlock_init(&legacy_hpet_event.cpumask_lock); wmb(); legacy_hpet_event.event_handler = handle_hpet_broadcast; @@ -716,9 +703,7 @@ void hpet_broadcast_exit(void) if ( !reprogram_timer(this_cpu(timer_deadline)) ) raise_softirq(TIMER_SOFTIRQ); - read_lock_irq(&ch->cpumask_lock); cpu_clear(cpu, ch->cpumask); - read_unlock_irq(&ch->cpumask_lock); if ( ch != &legacy_hpet_event ) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor