{
s_time_t deadline;
- rmb();
- deadline = per_cpu(timer_deadline, cpu);
- rmb();
if ( !cpumask_test_cpu(cpu, ch->cpumask) )
continue;
+ deadline = ACCESS_ONCE(per_cpu(timer_deadline, cpu));
+
if ( deadline <= now )
__cpumask_set_cpu(cpu, &mask);
else if ( deadline < next_event )
{
unsigned int cpu = smp_processor_id();
struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
+ s_time_t deadline = per_cpu(timer_deadline, cpu);
- if ( per_cpu(timer_deadline, cpu) == 0 )
+ if ( deadline == 0 )
return;
if ( !ch )
cpumask_set_cpu(cpu, ch->cpumask);
spin_lock(&ch->lock);
- /* reprogram if current cpu expire time is nearer */
- if ( per_cpu(timer_deadline, cpu) < ch->next_event )
- reprogram_hpet_evt_channel(ch, per_cpu(timer_deadline, cpu), NOW(), 1);
+ /*
+ * Reprogram if current cpu expire time is nearer. deadline is never
+ * written by a remote cpu, so the value read earlier is still valid.
+ */
+ if ( deadline < ch->next_event )
+ reprogram_hpet_evt_channel(ch, deadline, NOW(), 1);
spin_unlock(&ch->lock);
}
{
unsigned int cpu = smp_processor_id();
struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
+ s_time_t deadline = per_cpu(timer_deadline, cpu);
- if ( per_cpu(timer_deadline, cpu) == 0 )
+ if ( deadline == 0 )
return;
if ( !ch )
/* Reprogram the deadline; trigger timer work now if it has passed. */
enable_APIC_timer();
- if ( !reprogram_timer(per_cpu(timer_deadline, cpu)) )
+ if ( !reprogram_timer(deadline) )
raise_softirq(TIMER_SOFTIRQ);
cpumask_clear_cpu(cpu, ch->cpumask);