[Cbe-oss-dev] [PATCH 3/3] spufs: Fix memory leak on SPU affinity

Jeremy Kerr jk at ozlabs.org
Fri Jan 11 15:03:26 EST 2008


From: Andre Detsch <adetsch at br.ibm.com>

Reference count for the "neighbor" spu context was not
being correctly decremented after usage.
So, contexts used as reference during SPU affinity setup
were not being deallocated, leading to a memory leak.

Signed-off-by: Andre Detsch <adetsch at br.ibm.com>
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>

---
 arch/powerpc/platforms/cell/spufs/inode.c |   29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index c0e968a..90784c0 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -322,7 +322,7 @@ static struct spu_context *
 spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
 						struct file *filp)
 {
-	struct spu_context *tmp, *neighbor;
+	struct spu_context *tmp, *neighbor, *err;
 	int count, node;
 	int aff_supp;
 
@@ -354,11 +354,15 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
 		if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) &&
 		    !list_is_last(&neighbor->aff_list, &gang->aff_list_head) &&
 		    !list_entry(neighbor->aff_list.next, struct spu_context,
-		    aff_list)->aff_head)
-			return ERR_PTR(-EEXIST);
+		    aff_list)->aff_head) {
+			err = ERR_PTR(-EEXIST);
+			goto out_put_neighbor;
+		}
 
-		if (gang != neighbor->gang)
-			return ERR_PTR(-EINVAL);
+		if (gang != neighbor->gang) {
+			err = ERR_PTR(-EINVAL);
+			goto out_put_neighbor;
+		}
 
 		count = 1;
 		list_for_each_entry(tmp, &gang->aff_list_head, aff_list)
@@ -372,11 +376,17 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
 				break;
 		}
 
-		if (node == MAX_NUMNODES)
-			return ERR_PTR(-EEXIST);
+		if (node == MAX_NUMNODES) {
+			err = ERR_PTR(-EEXIST);
+			goto out_put_neighbor;
+		}
 	}
 
 	return neighbor;
+
+out_put_neighbor:
+	put_spu_context(neighbor);
+	return err;
 }
 
 static void
@@ -454,9 +464,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
 	if (ret)
 		goto out_aff_unlock;
 
-	if (affinity)
+	if (affinity) {
 		spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx,
 								neighbor);
+		if (neighbor)
+			put_spu_context(neighbor);
+	}
 
 	/*
 	 * get references for dget and mntget, will be released



More information about the cbe-oss-dev mailing list