aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c18
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c22
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h1
-rw-r--r--include/asm-powerpc/spu.h18
4 files changed, 58 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index e2c9d48a6804..e0d730045260 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1487,6 +1487,21 @@ static u64 spufs_id_get(void *data)
1487} 1487}
1488DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") 1488DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
1489 1489
1490static u64 spufs_object_id_get(void *data)
1491{
1492 struct spu_context *ctx = data;
1493 return ctx->object_id;
1494}
1495
1496static void spufs_object_id_set(void *data, u64 id)
1497{
1498 struct spu_context *ctx = data;
1499 ctx->object_id = id;
1500}
1501
1502DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
1503 spufs_object_id_set, "0x%llx\n");
1504
1490struct tree_descr spufs_dir_contents[] = { 1505struct tree_descr spufs_dir_contents[] = {
1491 { "mem", &spufs_mem_fops, 0666, }, 1506 { "mem", &spufs_mem_fops, 0666, },
1492 { "regs", &spufs_regs_fops, 0666, }, 1507 { "regs", &spufs_regs_fops, 0666, },
@@ -1510,7 +1525,8 @@ struct tree_descr spufs_dir_contents[] = {
1510 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, 1525 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
1511 { "event_mask", &spufs_event_mask_ops, 0666, }, 1526 { "event_mask", &spufs_event_mask_ops, 0666, },
1512 { "srr0", &spufs_srr0_ops, 0666, }, 1527 { "srr0", &spufs_srr0_ops, 0666, },
1513 { "phys-id", &spufs_id_ops, 0666, },
1514 { "psmap", &spufs_psmap_fops, 0666, }, 1528 { "psmap", &spufs_psmap_fops, 0666, },
1529 { "phys-id", &spufs_id_ops, 0666, },
1530 { "object-id", &spufs_object_id_ops, 0666, },
1515 {}, 1531 {},
1516}; 1532};
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index a824b6051164..bd6fe4b7a84b 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -35,6 +35,7 @@
35#include <linux/unistd.h> 35#include <linux/unistd.h>
36#include <linux/numa.h> 36#include <linux/numa.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38#include <linux/notifier.h>
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/mmu_context.h> 41#include <asm/mmu_context.h>
@@ -75,6 +76,25 @@ static inline void mm_needs_global_tlbie(struct mm_struct *mm)
75 __cpus_setall(&mm->cpu_vm_mask, nr); 76 __cpus_setall(&mm->cpu_vm_mask, nr);
76} 77}
77 78
79static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier);
80
81static void spu_switch_notify(struct spu *spu, struct spu_context *ctx)
82{
83 blocking_notifier_call_chain(&spu_switch_notifier,
84 ctx ? ctx->object_id : 0, spu);
85}
86
87int spu_switch_event_register(struct notifier_block * n)
88{
89 return blocking_notifier_chain_register(&spu_switch_notifier, n);
90}
91
92int spu_switch_event_unregister(struct notifier_block * n)
93{
94 return blocking_notifier_chain_unregister(&spu_switch_notifier, n);
95}
96
97
78static inline void bind_context(struct spu *spu, struct spu_context *ctx) 98static inline void bind_context(struct spu *spu, struct spu_context *ctx)
79{ 99{
80 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 100 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)
97 spu_restore(&ctx->csa, spu); 117 spu_restore(&ctx->csa, spu);
98 spu->timestamp = jiffies; 118 spu->timestamp = jiffies;
99 spu_cpu_affinity_set(spu, raw_smp_processor_id()); 119 spu_cpu_affinity_set(spu, raw_smp_processor_id());
120 spu_switch_notify(spu, ctx);
100} 121}
101 122
102static inline void unbind_context(struct spu *spu, struct spu_context *ctx) 123static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
103{ 124{
104 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 125 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
105 spu->pid, spu->number, spu->node); 126 spu->pid, spu->number, spu->node);
127 spu_switch_notify(spu, NULL);
106 spu_unmap_mappings(ctx); 128 spu_unmap_mappings(ctx);
107 spu_save(&ctx->csa, spu); 129 spu_save(&ctx->csa, spu);
108 spu->timestamp = jiffies; 130 spu->timestamp = jiffies;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index f6624ceedf70..a0f55ca2d488 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -50,6 +50,7 @@ struct spu_context {
50 struct address_space *cntl; /* 'control' area mappings. */ 50 struct address_space *cntl; /* 'control' area mappings. */
51 struct address_space *signal1; /* 'signal1' area mappings. */ 51 struct address_space *signal1; /* 'signal1' area mappings. */
52 struct address_space *signal2; /* 'signal2' area mappings. */ 52 struct address_space *signal2; /* 'signal2' area mappings. */
53 u64 object_id; /* user space pointer for oprofile */
53 54
54 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 55 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
55 struct rw_semaphore state_sema; 56 struct rw_semaphore state_sema;
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 83b6dae48efc..e73ea00efd8b 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -201,6 +201,24 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls)
201 201
202 202
203/* 203/*
204 * Notifier blocks:
205 *
206 * oprofile can get notified when a context switch is performed
207 * on an spe. The notifer function that gets called is passed
208 * a pointer to the SPU structure as well as the object-id that
209 * identifies the binary running on that SPU now.
210 *
211 * For a context save, the object-id that is passed is zero,
212 * identifying that the kernel will run from that moment on.
213 *
214 * For a context restore, the object-id is the value written
215 * to object-id spufs file from user space and the notifer
216 * function can assume that spu->ctx is valid.
217 */
218int spu_switch_event_register(struct notifier_block * n);
219int spu_switch_event_unregister(struct notifier_block * n);
220
221/*
204 * This defines the Local Store, Problem Area and Privlege Area of an SPU. 222 * This defines the Local Store, Problem Area and Privlege Area of an SPU.
205 */ 223 */
206 224