]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/cell/spufs/sched.c
[POWERPC] spufs: don't requeue victim contex in find_victim if it's not in spu_run
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / spufs / sched.c
index 5915343e2599b313320b2ca18edb42cdecec60e2..8a05ac863a27b0f614e01816dbd97508c7666f3c 100644 (file)
@@ -140,6 +140,9 @@ void __spu_update_sched_info(struct spu_context *ctx)
         * 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)
@@ -240,13 +243,13 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
        spu->mfc_callback = spufs_mfc_callback;
        mb();
        spu_unmap_mappings(ctx);
+       spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0);
        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;
 
-       spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
+       spuctx_switch_state(ctx, SPU_UTIL_USER);
 }
 
 /*
@@ -419,6 +422,7 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
        spu_switch_notify(spu, NULL);
        spu_unmap_mappings(ctx);
        spu_save(&ctx->csa, spu);
+       spu_switch_log_notify(spu, ctx, SWITCH_LOG_STOP, 0);
        spu->timestamp = jiffies;
        ctx->state = SPU_STATE_SAVED;
        spu->ibox_callback = NULL;
@@ -591,7 +595,7 @@ static struct spu *find_victim(struct spu_context *ctx)
        struct spu *spu;
        int node, n;
 
-       spu_context_nospu_trace(spu_find_vitim__enter, ctx);
+       spu_context_nospu_trace(spu_find_victim__enter, ctx);
 
        /*
         * Look for a possible preemption candidate on the local node first.
@@ -655,7 +659,8 @@ static struct spu *find_victim(struct spu_context *ctx)
 
                        victim->stats.invol_ctx_switch++;
                        spu->stats.invol_ctx_switch++;
-                       spu_add_to_rq(victim);
+                       if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
+                               spu_add_to_rq(victim);
 
                        mutex_unlock(&victim->state_mutex);
 
@@ -856,21 +861,18 @@ static noinline void spusched_tick(struct spu_context *ctx)
 {
        struct spu_context *new = NULL;
        struct spu *spu = NULL;
-       u32 status;
 
        if (spu_acquire(ctx))
                BUG();  /* a kernel thread never has signals pending */
 
        if (ctx->state != SPU_STATE_RUNNABLE)
                goto out;
-       if (spu_stopped(ctx, &status))
-               goto out;
        if (ctx->flags & SPU_CREATE_NOSCHED)
                goto out;
        if (ctx->policy == SCHED_FIFO)
                goto out;
 
-       if (--ctx->time_slice)
+       if (--ctx->time_slice && test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
                goto out;
 
        spu = ctx->spu;
@@ -880,7 +882,8 @@ static noinline void spusched_tick(struct spu_context *ctx)
        new = grab_runnable_context(ctx->prio + 1, spu->node);
        if (new) {
                spu_unschedule(spu, ctx);
-               spu_add_to_rq(ctx);
+               if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
+                       spu_add_to_rq(ctx);
        } else {
                spu_context_nospu_trace(spusched_tick__newslice, ctx);
                ctx->time_slice++;