diff mbox

(no subject)

Message ID 200812101904.mBAJ4HP3016198@d24av01.br.ibm.com
State Superseded
Headers show

Commit Message

Andre Detsch Dec. 10, 2008, 7:04 p.m. UTC
From 639b768d8134b10046407545c11dbbd8a6577c80 Mon Sep 17 00:00:00 2001
In-Reply-To: <200812101654.05091.adetsch@br.ibm.com>
References: <200812101654.05091.adetsch@br.ibm.com>
From: Andre Detsch <adetsch@br.ibm.com>
Date: Wed, 10 Dec 2008 17:04:18 -0200
Subject: [PATCH 14/18] powerpc/spufs: Fix gang deactivation when gang grows or shrinks
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Message-Id: <200812101704.18205.adetsch@br.ibm.com>

The gang deactivation must be done in the same critical section
as the list_add/list_del operation, otherwise there is no guarantee
that the grow/shrink is correctly done.

Signed-off-by: Andre Detsch <adetsch@br.ibm.com>
---
 arch/powerpc/platforms/cell/spufs/context.c |   19 -------------------
 arch/powerpc/platforms/cell/spufs/gang.c    |   11 +++++++++++
 2 files changed, 11 insertions(+), 19 deletions(-)
diff mbox

Patch

diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 0e37eff..ef81894 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -79,17 +79,6 @@  struct spu_context *alloc_spu_context(struct spu_gang *gang)
 
 	inc_active_gangs(gang);
 
-	/* If the gang is running, it needs to be stopped, since we have a
-	 * new context that needs to be gang scheduled.  Gangs are allowed
-	 * to grow and shrink over time, but they are unscheduled when it
-	 * happens as the gang may need to migrated to a different node.
-	 */
-	if (atomic_read(&gang->nstarted)) {
-		mutex_lock(&gang->mutex);
-		spu_deactivate(gang);
-		mutex_unlock(&gang->mutex);
-	}
-
 	spin_lock_init(&ctx->mmio_lock);
 	mutex_init(&ctx->mapping_lock);
 	kref_init(&ctx->kref);
@@ -141,14 +130,6 @@  void destroy_spu_context(struct kref *kref)
 
 	spu_context_nospu_trace(destroy_spu_context__enter, ctx);
 
-	/*
-	 * Deactivate and make it non-runnable while we work on it.
-	 */
-	mutex_lock(&gang->mutex);
-	WARN_ON(ctx->gang != gang);
-	spu_deactivate(gang);
-	mutex_unlock(&gang->mutex);
-
 	spu_fini_csa(&ctx->csa);
 	spu_gang_remove_ctx(ctx->gang, ctx);
 	if (ctx->prof_priv_kref)
diff --git a/arch/powerpc/platforms/cell/spufs/gang.c b/arch/powerpc/platforms/cell/spufs/gang.c
index 7b1513d..7e9ab01 100644
--- a/arch/powerpc/platforms/cell/spufs/gang.c
+++ b/arch/powerpc/platforms/cell/spufs/gang.c
@@ -90,6 +90,15 @@  int put_spu_gang(struct spu_gang *gang)
 void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx)
 {
 	mutex_lock(&gang->mutex);
+	/*
+	 * If the gang is running, it needs to be stopped, since we have a
+	 * new context that needs to be gang scheduled.  Gangs are allowed
+	 * to grow and shrink over time, but they are unscheduled when it
+	 * happens as the gang may need to migrated to a different node.
+	 */
+	if (atomic_read(&gang->nstarted))
+		spu_deactivate(gang);
+
 	ctx->gang = get_spu_gang(gang);
 	list_add(&ctx->gang_list, &gang->list);
 	gang->contexts++;
@@ -115,7 +124,9 @@  void update_gang_stats(struct spu_gang *gang, struct spu_context *ctx)
 void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx)
 {
 	mutex_lock(&gang->mutex);
+	/* Deactivate and make it non-runnable while we work on it. */
 	WARN_ON(ctx->gang != gang);
+	spu_deactivate(gang);
 	if (!list_empty(&ctx->aff_list)) {
 		list_del_init(&ctx->aff_list);
 		gang->aff_flags &= ~AFF_OFFSETS_SET;