[Cbe-oss-dev] [PATCH 3:5] spusched: fix spu interrupt routine

Luke Browning lukebr at linux.vnet.ibm.com
Mon Apr 28 04:45:20 EST 2008


Fix spu interrupt routining

Route mfc interrupts to the cpu where the controlling thread last ran
provided that cpu is on the same node as the spu.  Otherwise don't 
reroute interrupts.  Code previously routed to the current cpu which 
could may have been on a remote node.  In the case of time slicing all
spu interrupts were routed to one cpu.  This should improve performance.

Signed-off-by: Luke Browning <lukebr at linux.vnet.ibm.com>

---

Index: spufs/arch/powerpc/platforms/cell/spu_priv1_mmio.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spu_priv1_mmio.c
+++ spufs/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/sched.h>
 
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
@@ -75,8 +76,19 @@ static u64 int_stat_get(struct spu *spu,
 
 static void cpu_affinity_set(struct spu *spu, int cpu)
 {
-	u64 target = iic_get_target_id(cpu);
-	u64 route = target << 48 | target << 32 | target << 16;
+	u64 target;
+	u64 route;
+
+	if (nr_cpus_node(spu->node)) {
+		cpumask_t spumask = node_to_cpumask(spu->node);
+		cpumask_t cpumask = node_to_cpumask(cpu_to_node(cpu));
+
+		if (!cpus_intersects(spumask, cpumask))
+			return;
+	}
+
+	target = iic_get_target_id(cpu);
+	route = target << 48 | target << 32 | target << 16;
 	out_be64(&spu->priv1->int_route_RW, route);
 }
 
Index: spufs/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/sched.c
+++ spufs/arch/powerpc/platforms/cell/spufs/sched.c
@@ -140,6 +140,9 @@ void __spu_update_sched_info(struct spu_
 	 * if it is timesliced or preempted.
 	 */
 	ctx->cpus_allowed = current->cpus_allowed;
+
+	/* Save the current cpu id for spu interrupt routing. */
+	ctx->last_ran = raw_smp_processor_id();
 }
 
 void spu_update_sched_info(struct spu_context *ctx)
@@ -242,7 +245,6 @@ static void spu_bind_context(struct spu 
 	spu_unmap_mappings(ctx);
 	spu_restore(&ctx->csa, spu);
 	spu->timestamp = jiffies;
-	spu_cpu_affinity_set(spu, raw_smp_processor_id());
 	spu_switch_notify(spu, ctx);
 	ctx->state = SPU_STATE_RUNNABLE;
 
Index: spufs/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/spufs.h
+++ spufs/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -97,6 +97,7 @@ struct spu_context {
 	cpumask_t cpus_allowed;
 	int policy;
 	int prio;
+	int last_ran;
 
 	/* statistics */
 	struct {
Index: spufs/arch/powerpc/platforms/cell/spufs/switch.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/switch.c
+++ spufs/arch/powerpc/platforms/cell/spufs/switch.c
@@ -1709,6 +1709,13 @@ static inline void restore_mfc_sr1(struc
 	eieio();
 }
 
+static inline void set_int_route(struct spu_state *csa, struct spu *spu)
+{
+	struct spu_context *ctx = spu->ctx;
+
+	spu_cpu_affinity_set(spu, ctx->last_ran);
+}
+
 static inline void restore_other_spu_access(struct spu_state *csa,
 					    struct spu *spu)
 {
@@ -2021,6 +2028,7 @@ static void restore_csa(struct spu_state
 	check_ppuint_mb_stat(next, spu);	/* Step 67. */
 	spu_invalidate_slbs(spu);		/* Modified Step 68. */
 	restore_mfc_sr1(next, spu);	        /* Step 69. */
+	set_int_route(next, spu);		/* NEW      */
 	restore_other_spu_access(next, spu);	/* Step 70. */
 	restore_spu_runcntl(next, spu);	        /* Step 71. */
 	restore_mfc_cntl(next, spu);	        /* Step 72. */





More information about the cbe-oss-dev mailing list