From cbcdb93d4443568f17e93610d240043ec5ac067b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 17 Oct 2006 23:08:35 +1000 Subject: [POWERPC] Simplify stolen time calculation In calculating stolen time, we were trying to actually account for time spent in the hypervisor. We don't really have enough information to do that accurately, so don't try. Instead, we now calculate stolen time as time that the current cpu thread is not actually dispatching instructions. On chips without a PURR, we cannot do this, so stolen time will always be zero. On chips with a PURR, this is merely the difference between the elapsed PURR values and the elapsed TB values. This gives us much more sane vaules from tools such as mpstat, even if they are still a bit strange e.g. 2 busy threads on one cpu will both appear to have 50% user time and 50% stolen time while 1 busy thread on a cpu will look like 100% user on one of them and 100% idle on the other. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 63 ++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 47 deletions(-) (limited to 'arch/powerpc/kernel/time.c') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 5b59bc18dfe7..a1b5e4b16151 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -220,11 +220,8 @@ static void account_process_time(struct pt_regs *regs) */ struct cpu_purr_data { int initialized; /* thread is running */ - u64 tb0; /* timebase at origin time */ - u64 purr0; /* PURR at origin time */ u64 tb; /* last TB value read */ u64 purr; /* last PURR value read */ - u64 stolen; /* stolen time so far */ spinlock_t lock; }; @@ -234,10 +231,8 @@ static void snapshot_tb_and_purr(void *data) { struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); - p->tb0 = mftb(); - p->purr0 = mfspr(SPRN_PURR); - p->tb = p->tb0; - p->purr = 0; + p->tb = mftb(); + p->purr = mfspr(SPRN_PURR); wmb(); p->initialized = 1; } @@ -258,37 +253,24 @@ void snapshot_timebases(void) void calculate_steal_time(void) { - u64 tb, purr, t0; + u64 tb, purr; s64 stolen; - struct cpu_purr_data *p0, *pme, *phim; - int cpu; + struct cpu_purr_data *pme; if (!cpu_has_feature(CPU_FTR_PURR)) return; - cpu = smp_processor_id(); - pme = &per_cpu(cpu_purr_data, cpu); + pme = &per_cpu(cpu_purr_data, smp_processor_id()); if (!pme->initialized) return; /* this can happen in early boot */ - p0 = &per_cpu(cpu_purr_data, cpu & ~1); - phim = &per_cpu(cpu_purr_data, cpu ^ 1); - spin_lock(&p0->lock); + spin_lock(&pme->lock); tb = mftb(); - purr = mfspr(SPRN_PURR) - pme->purr0; - if (!phim->initialized || !cpu_online(cpu ^ 1)) { - stolen = (tb - pme->tb) - (purr - pme->purr); - } else { - t0 = pme->tb0; - if (phim->tb0 < t0) - t0 = phim->tb0; - stolen = phim->tb - t0 - phim->purr - purr - p0->stolen; - } - if (stolen > 0) { + purr = mfspr(SPRN_PURR); + stolen = (tb - pme->tb) - (purr - pme->purr); + if (stolen > 0) account_steal_time(current, stolen); - p0->stolen += stolen; - } pme->tb = tb; pme->purr = purr; - spin_unlock(&p0->lock); + spin_unlock(&pme->lock); } /* @@ -297,30 +279,17 @@ void calculate_steal_time(void) */ static void snapshot_purr(void) { - int cpu; - u64 purr; - struct cpu_purr_data *p0, *pme, *phim; + struct cpu_purr_data *pme; unsigned long flags; if (!cpu_has_feature(CPU_FTR_PURR)) return; - cpu = smp_processor_id(); - pme = &per_cpu(cpu_purr_data, cpu); - p0 = &per_cpu(cpu_purr_data, cpu & ~1); - phim = &per_cpu(cpu_purr_data, cpu ^ 1); - spin_lock_irqsave(&p0->lock, flags); - pme->tb = pme->tb0 = mftb(); - purr = mfspr(SPRN_PURR); - if (!phim->initialized) { - pme->purr = 0; - pme->purr0 = purr; - } else { - /* set p->purr and p->purr0 for no change in p0->stolen */ - pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen; - pme->purr0 = purr - pme->purr; - } + pme = &per_cpu(cpu_purr_data, smp_processor_id()); + spin_lock_irqsave(&pme->lock, flags); + pme->tb = mftb(); + pme->purr = mfspr(SPRN_PURR); pme->initialized = 1; - spin_unlock_irqrestore(&p0->lock, flags); + spin_unlock_irqrestore(&pme->lock, flags); } #endif /* CONFIG_PPC_SPLPAR */ -- cgit v1.2.3