diff options
| author | Andre Detsch <adetsch@br.ibm.com> | 2007-07-20 15:39:33 -0400 |
|---|---|---|
| committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-07-20 15:41:50 -0400 |
| commit | 27ec41d3a1d4df2b7cd190e93aad22ab86a72aa1 (patch) | |
| tree | 6c9d5af3fc3c3cfbef390eb34caf4dc7e7a3913e | |
| parent | e840cfe6814d6f13ecb86cff7097ad7259df502e (diff) | |
[CELL] spufs: add spu stats in sysfs and ctx stat file in spufs
This patch exports per-context statistics in spufs as long as spu
statistics in sysfs.
It was formed by merging:
"spufs: add spu stats in sysfs" From: Christoph Hellwig
"spufs: add stat file to spufs" From: Christoph Hellwig
"spufs: fix libassist accounting" From: Jeremy Kerr
"spusched: fix spu utilization statistics" From: Luke Browning
And some adjustments by myself, after suggestions on cbe-oss-dev.
Having separate patches was making the review process harder
than it should, as we end up integrating spus and ctx statistics
accounting much more than it was on the first implementation.
Signed-off-by: Andre Detsch <adetsch@br.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
| -rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 24 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/fault.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 32 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 22 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 63 | ||||
| -rw-r--r-- | include/asm-powerpc/spu.h | 10 |
8 files changed, 94 insertions, 78 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index c563066e640d..caaf2bf78cad 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -553,6 +553,7 @@ static int __init create_spu(void *data) | |||
| 553 | int ret; | 553 | int ret; |
| 554 | static int number; | 554 | static int number; |
| 555 | unsigned long flags; | 555 | unsigned long flags; |
| 556 | struct timespec ts; | ||
| 556 | 557 | ||
| 557 | ret = -ENOMEM; | 558 | ret = -ENOMEM; |
| 558 | spu = kzalloc(sizeof (*spu), GFP_KERNEL); | 559 | spu = kzalloc(sizeof (*spu), GFP_KERNEL); |
| @@ -586,8 +587,9 @@ static int __init create_spu(void *data) | |||
| 586 | spin_unlock_irqrestore(&spu_list_lock, flags); | 587 | spin_unlock_irqrestore(&spu_list_lock, flags); |
| 587 | mutex_unlock(&spu_mutex); | 588 | mutex_unlock(&spu_mutex); |
| 588 | 589 | ||
| 589 | spu->stats.utilization_state = SPU_UTIL_IDLE; | 590 | spu->stats.util_state = SPU_UTIL_IDLE_LOADED; |
| 590 | spu->stats.tstamp = jiffies; | 591 | ktime_get_ts(&ts); |
| 592 | spu->stats.tstamp = timespec_to_ns(&ts); | ||
| 591 | 593 | ||
| 592 | goto out; | 594 | goto out; |
| 593 | 595 | ||
| @@ -608,12 +610,20 @@ static const char *spu_state_names[] = { | |||
| 608 | static unsigned long long spu_acct_time(struct spu *spu, | 610 | static unsigned long long spu_acct_time(struct spu *spu, |
| 609 | enum spu_utilization_state state) | 611 | enum spu_utilization_state state) |
| 610 | { | 612 | { |
| 613 | struct timespec ts; | ||
| 611 | unsigned long long time = spu->stats.times[state]; | 614 | unsigned long long time = spu->stats.times[state]; |
| 612 | 615 | ||
| 613 | if (spu->stats.utilization_state == state) | 616 | /* |
| 614 | time += jiffies - spu->stats.tstamp; | 617 | * If the spu is idle or the context is stopped, utilization |
| 618 | * statistics are not updated. Apply the time delta from the | ||
| 619 | * last recorded state of the spu. | ||
| 620 | */ | ||
| 621 | if (spu->stats.util_state == state) { | ||
| 622 | ktime_get_ts(&ts); | ||
| 623 | time += timespec_to_ns(&ts) - spu->stats.tstamp; | ||
| 624 | } | ||
| 615 | 625 | ||
| 616 | return jiffies_to_msecs(time); | 626 | return time / NSEC_PER_MSEC; |
| 617 | } | 627 | } |
| 618 | 628 | ||
| 619 | 629 | ||
| @@ -623,11 +633,11 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf) | |||
| 623 | 633 | ||
| 624 | return sprintf(buf, "%s %llu %llu %llu %llu " | 634 | return sprintf(buf, "%s %llu %llu %llu %llu " |
| 625 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", | 635 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", |
| 626 | spu_state_names[spu->stats.utilization_state], | 636 | spu_state_names[spu->stats.util_state], |
| 627 | spu_acct_time(spu, SPU_UTIL_USER), | 637 | spu_acct_time(spu, SPU_UTIL_USER), |
| 628 | spu_acct_time(spu, SPU_UTIL_SYSTEM), | 638 | spu_acct_time(spu, SPU_UTIL_SYSTEM), |
| 629 | spu_acct_time(spu, SPU_UTIL_IOWAIT), | 639 | spu_acct_time(spu, SPU_UTIL_IOWAIT), |
| 630 | spu_acct_time(spu, SPU_UTIL_IDLE), | 640 | spu_acct_time(spu, SPU_UTIL_IDLE_LOADED), |
| 631 | spu->stats.vol_ctx_switch, | 641 | spu->stats.vol_ctx_switch, |
| 632 | spu->stats.invol_ctx_switch, | 642 | spu->stats.invol_ctx_switch, |
| 633 | spu->stats.slb_flt, | 643 | spu->stats.slb_flt, |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 6d7bd60f5380..0e5e55f53c8b 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
| @@ -59,8 +59,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) | |||
| 59 | spu_gang_add_ctx(gang, ctx); | 59 | spu_gang_add_ctx(gang, ctx); |
| 60 | ctx->cpus_allowed = current->cpus_allowed; | 60 | ctx->cpus_allowed = current->cpus_allowed; |
| 61 | spu_set_timeslice(ctx); | 61 | spu_set_timeslice(ctx); |
| 62 | ctx->stats.execution_state = SPUCTX_UTIL_USER; | 62 | ctx->stats.util_state = SPU_UTIL_IDLE_LOADED; |
| 63 | ctx->stats.tstamp = jiffies; | ||
| 64 | 63 | ||
| 65 | atomic_inc(&nr_spu_contexts); | 64 | atomic_inc(&nr_spu_contexts); |
| 66 | goto out; | 65 | goto out; |
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index f53a07437472..917eab4be486 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c | |||
| @@ -179,16 +179,14 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
| 179 | if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) | 179 | if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) |
| 180 | return 0; | 180 | return 0; |
| 181 | 181 | ||
| 182 | spuctx_switch_state(ctx, SPUCTX_UTIL_IOWAIT); | 182 | spuctx_switch_state(ctx, SPU_UTIL_IOWAIT); |
| 183 | 183 | ||
| 184 | pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, | 184 | pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, |
| 185 | dsisr, ctx->state); | 185 | dsisr, ctx->state); |
| 186 | 186 | ||
| 187 | ctx->stats.hash_flt++; | 187 | ctx->stats.hash_flt++; |
| 188 | if (ctx->state == SPU_STATE_RUNNABLE) { | 188 | if (ctx->state == SPU_STATE_RUNNABLE) |
| 189 | ctx->spu->stats.hash_flt++; | 189 | ctx->spu->stats.hash_flt++; |
| 190 | spu_switch_state(ctx->spu, SPU_UTIL_IOWAIT); | ||
| 191 | } | ||
| 192 | 190 | ||
| 193 | /* we must not hold the lock when entering spu_handle_mm_fault */ | 191 | /* we must not hold the lock when entering spu_handle_mm_fault */ |
| 194 | spu_release(ctx); | 192 | spu_release(ctx); |
| @@ -226,7 +224,7 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
| 226 | } else | 224 | } else |
| 227 | spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); | 225 | spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); |
| 228 | 226 | ||
| 229 | spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM); | 227 | spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); |
| 230 | return ret; | 228 | return ret; |
| 231 | } | 229 | } |
| 232 | EXPORT_SYMBOL_GPL(spufs_handle_class1); | 230 | EXPORT_SYMBOL_GPL(spufs_handle_class1); |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index fe164112b3d0..9351db9472d9 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
| @@ -2079,14 +2079,26 @@ static const char *ctx_state_names[] = { | |||
| 2079 | }; | 2079 | }; |
| 2080 | 2080 | ||
| 2081 | static unsigned long long spufs_acct_time(struct spu_context *ctx, | 2081 | static unsigned long long spufs_acct_time(struct spu_context *ctx, |
| 2082 | enum spuctx_execution_state state) | 2082 | enum spu_utilization_state state) |
| 2083 | { | 2083 | { |
| 2084 | unsigned long time = ctx->stats.times[state]; | 2084 | struct timespec ts; |
| 2085 | unsigned long long time = ctx->stats.times[state]; | ||
| 2085 | 2086 | ||
| 2086 | if (ctx->stats.execution_state == state) | 2087 | /* |
| 2087 | time += jiffies - ctx->stats.tstamp; | 2088 | * In general, utilization statistics are updated by the controlling |
| 2089 | * thread as the spu context moves through various well defined | ||
| 2090 | * state transitions, but if the context is lazily loaded its | ||
| 2091 | * utilization statistics are not updated as the controlling thread | ||
| 2092 | * is not tightly coupled with the execution of the spu context. We | ||
| 2093 | * calculate and apply the time delta from the last recorded state | ||
| 2094 | * of the spu context. | ||
| 2095 | */ | ||
| 2096 | if (ctx->spu && ctx->stats.util_state == state) { | ||
| 2097 | ktime_get_ts(&ts); | ||
| 2098 | time += timespec_to_ns(&ts) - ctx->stats.tstamp; | ||
| 2099 | } | ||
| 2088 | 2100 | ||
| 2089 | return jiffies_to_msecs(time); | 2101 | return time / NSEC_PER_MSEC; |
| 2090 | } | 2102 | } |
| 2091 | 2103 | ||
| 2092 | static unsigned long long spufs_slb_flts(struct spu_context *ctx) | 2104 | static unsigned long long spufs_slb_flts(struct spu_context *ctx) |
| @@ -2121,11 +2133,11 @@ static int spufs_show_stat(struct seq_file *s, void *private) | |||
| 2121 | spu_acquire(ctx); | 2133 | spu_acquire(ctx); |
| 2122 | seq_printf(s, "%s %llu %llu %llu %llu " | 2134 | seq_printf(s, "%s %llu %llu %llu %llu " |
| 2123 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", | 2135 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", |
| 2124 | ctx_state_names[ctx->stats.execution_state], | 2136 | ctx_state_names[ctx->stats.util_state], |
| 2125 | spufs_acct_time(ctx, SPUCTX_UTIL_USER), | 2137 | |
