]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/cell/spufs/context.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / spufs / context.c
index 6fa24d38706ea7d96b43f8159236c0c874689676..6653ddbed0483c4679755ee23b132fbc57091cb3 100644 (file)
@@ -78,6 +78,7 @@ void destroy_spu_context(struct kref *kref)
 {
        struct spu_context *ctx;
        ctx = container_of(kref, struct spu_context, kref);
+       spu_context_nospu_trace(destroy_spu_context__enter, ctx);
        mutex_lock(&ctx->state_mutex);
        spu_deactivate(ctx);
        mutex_unlock(&ctx->state_mutex);
@@ -88,6 +89,7 @@ void destroy_spu_context(struct kref *kref)
                kref_put(ctx->prof_priv_kref, ctx->prof_priv_release);
        BUG_ON(!list_empty(&ctx->rq));
        atomic_dec(&nr_spu_contexts);
+       kfree(ctx->switch_log);
        kfree(ctx);
 }
 
@@ -106,7 +108,16 @@ int put_spu_context(struct spu_context *ctx)
 void spu_forget(struct spu_context *ctx)
 {
        struct mm_struct *mm;
-       spu_acquire_saved(ctx);
+
+       /*
+        * This is basically an open-coded spu_acquire_saved, except that
+        * we don't acquire the state mutex interruptible, and we don't
+        * want this context to be rescheduled on release.
+        */
+       mutex_lock(&ctx->state_mutex);
+       if (ctx->state != SPU_STATE_SAVED)
+               spu_deactivate(ctx);
+
        mm = ctx->owner;
        ctx->owner = NULL;
        mmput(mm);
@@ -119,62 +130,40 @@ void spu_unmap_mappings(struct spu_context *ctx)
        if (ctx->local_store)
                unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
        if (ctx->mfc)
-               unmap_mapping_range(ctx->mfc, 0, 0x1000, 1);
+               unmap_mapping_range(ctx->mfc, 0, SPUFS_MFC_MAP_SIZE, 1);
        if (ctx->cntl)
-               unmap_mapping_range(ctx->cntl, 0, 0x1000, 1);
+               unmap_mapping_range(ctx->cntl, 0, SPUFS_CNTL_MAP_SIZE, 1);
        if (ctx->signal1)
-               unmap_mapping_range(ctx->signal1, 0, PAGE_SIZE, 1);
+               unmap_mapping_range(ctx->signal1, 0, SPUFS_SIGNAL_MAP_SIZE, 1);
        if (ctx->signal2)
-               unmap_mapping_range(ctx->signal2, 0, PAGE_SIZE, 1);
+               unmap_mapping_range(ctx->signal2, 0, SPUFS_SIGNAL_MAP_SIZE, 1);
        if (ctx->mss)
-               unmap_mapping_range(ctx->mss, 0, 0x1000, 1);
+               unmap_mapping_range(ctx->mss, 0, SPUFS_MSS_MAP_SIZE, 1);
        if (ctx->psmap)
-               unmap_mapping_range(ctx->psmap, 0, 0x20000, 1);
+               unmap_mapping_range(ctx->psmap, 0, SPUFS_PS_MAP_SIZE, 1);
        mutex_unlock(&ctx->mapping_lock);
 }
 
 /**
- * spu_acquire_runnable - lock spu contex and make sure it is in runnable state
+ * spu_acquire_saved - lock spu contex and make sure it is in saved state
  * @ctx:       spu contex to lock
- *
- * Note:
- *     Returns 0 and with the context locked on success
- *     Returns negative error and with the context _unlocked_ on failure.
  */
-int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags)
+int spu_acquire_saved(struct spu_context *ctx)
 {
-       int ret = -EINVAL;
-
-       spu_acquire(ctx);
-       if (ctx->state == SPU_STATE_SAVED) {
-               /*
-                * Context is about to be freed, so we can't acquire it anymore.
-                */
-               if (!ctx->owner)
-                       goto out_unlock;
-               ret = spu_activate(ctx, flags);
-               if (ret)
-                       goto out_unlock;
-       }
+       int ret;
 
-       return 0;
+       spu_context_nospu_trace(spu_acquire_saved__enter, ctx);
 
- out_unlock:
-       spu_release(ctx);
-       return ret;
-}
+       ret = spu_acquire(ctx);
+       if (ret)
+               return ret;
 
-/**
- * spu_acquire_saved - lock spu contex and make sure it is in saved state
- * @ctx:       spu contex to lock
- */
-void spu_acquire_saved(struct spu_context *ctx)
-{
-       spu_acquire(ctx);
        if (ctx->state != SPU_STATE_SAVED) {
                set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
                spu_deactivate(ctx);
        }
+
+       return 0;
 }
 
 /**
@@ -185,25 +174,10 @@ void spu_release_saved(struct spu_context *ctx)
 {
        BUG_ON(ctx->state != SPU_STATE_SAVED);
 
-       if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags))
+       if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags) &&
+                       test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
                spu_activate(ctx, 0);
 
        spu_release(ctx);
 }
 
-void spu_set_profile_private_kref(struct spu_context *ctx,
-                                 struct kref *prof_info_kref,
-                                 void ( * prof_info_release) (struct kref *kref))
-{
-       ctx->prof_priv_kref = prof_info_kref;
-       ctx->prof_priv_release = prof_info_release;
-}
-EXPORT_SYMBOL_GPL(spu_set_profile_private_kref);
-
-void *spu_get_profile_private_kref(struct spu_context *ctx)
-{
-       return ctx->prof_priv_kref;
-}
-EXPORT_SYMBOL_GPL(spu_get_profile_private_kref);
-
-