Skip to content

Commit

Permalink
[POWERPC] Simplify stolen time calculation
Browse files Browse the repository at this point in the history
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 <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Stephen Rothwell authored and Paul Mackerras committed Oct 23, 2006
1 parent 5cfc35c commit cbcdb93
Showing 1 changed file with 16 additions and 47 deletions.
63 changes: 16 additions & 47 deletions arch/powerpc/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand All @@ -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;
}
Expand All @@ -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);
}

/*
Expand All @@ -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 */
Expand Down

0 comments on commit cbcdb93

Please sign in to comment.