diff options
author | Arnd Bergmann <arnd@arndb.de> | 2006-10-04 17:26:21 +0200 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-10-05 09:21:02 +1000 |
commit | 867672777964b9309e4e914fe097648c938b67b2 (patch) | |
tree | ef37d5252aa35497e96acf6b0e29e56894e6ab77 /arch/powerpc/platforms/cell/spufs/sched.c | |
parent | 7650f2f2c367242a2092908794b4486876baf6c7 (diff) |
[POWERPC] spufs: add infrastructure for finding elf objects
This adds an 'object-id' file that the spe library can
use to store a pointer to its ELF object. This was
originally meant for use by oprofile, but is now
also used by the GNU debugger, if available.
In order for oprofile to find the location in an spu-elf
binary where an event counter triggered, we need a way
to identify the binary in the first place.
Unfortunately, that binary itself can be embedded in a
powerpc ELF binary. Since we can assume it is mapped into
the effective address space of the running process,
have that one write the pointer value into a new spufs
file.
When a context switch occurs, pass the user value to
the profiler so that can look at the mapped file (with
some care).
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/sched.c')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index a824b605116..bd6fe4b7a84 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -35,6 +35,7 @@ #include <linux/unistd.h> #include <linux/numa.h> #include <linux/mutex.h> +#include <linux/notifier.h> #include <asm/io.h> #include <asm/mmu_context.h> @@ -75,6 +76,25 @@ static inline void mm_needs_global_tlbie(struct mm_struct *mm) __cpus_setall(&mm->cpu_vm_mask, nr); } +static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); + +static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) +{ + blocking_notifier_call_chain(&spu_switch_notifier, + ctx ? ctx->object_id : 0, spu); +} + +int spu_switch_event_register(struct notifier_block * n) +{ + return blocking_notifier_chain_register(&spu_switch_notifier, n); +} + +int spu_switch_event_unregister(struct notifier_block * n) +{ + return blocking_notifier_chain_unregister(&spu_switch_notifier, n); +} + + static inline void bind_context(struct spu *spu, struct spu_context *ctx) { pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, @@ -97,12 +117,14 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx) spu_restore(&ctx->csa, spu); spu->timestamp = jiffies; spu_cpu_affinity_set(spu, raw_smp_processor_id()); + spu_switch_notify(spu, ctx); } static inline void unbind_context(struct spu *spu, struct spu_context *ctx) { pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, spu->pid, spu->number, spu->node); + spu_switch_notify(spu, NULL); spu_unmap_mappings(ctx); spu_save(&ctx->csa, spu); spu->timestamp = jiffies; |