[S390] lockless idle time accounting

Replace the spinlock used in the idle time accounting with a sequence
counter mechanism analog to seqlock.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Martin Schwidefsky
2009-06-22 12:08:20 +02:00
parent 4f0076f77f
commit e98bbaafcd
3 changed files with 35 additions and 17 deletions

View File

@ -27,9 +27,7 @@
static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = {
.lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock)
};
DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
static inline __u64 get_vtimer(void)
{
@ -151,11 +149,13 @@ void vtime_start_cpu(void)
vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer;
}
spin_lock(&idle->lock);
idle->sequence++;
smp_wmb();
idle->idle_time += idle_time;
idle->idle_enter = 0ULL;
idle->idle_count++;
spin_unlock(&idle->lock);
smp_wmb();
idle->sequence++;
}
void vtime_stop_cpu(void)
@ -242,15 +242,23 @@ cputime64_t s390_get_idle_time(int cpu)
{
struct s390_idle_data *idle;
unsigned long long now, idle_time, idle_enter;
unsigned int sequence;
idle = &per_cpu(s390_idle, cpu);
spin_lock(&idle->lock);
now = get_clock();
repeat:
sequence = idle->sequence;
smp_rmb();
if (sequence & 1)
goto repeat;
idle_time = 0;
idle_enter = idle->idle_enter;
if (idle_enter != 0ULL && idle_enter < now)
idle_time = now - idle_enter;
spin_unlock(&idle->lock);
smp_rmb();
if (idle->sequence != sequence)
goto repeat;
return idle_time;
}