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

Andre Detsch adetsch at br.ibm.com
Fri Oct 19 08:24:30 EST 2007


Subject: spufs: Fix memory leak on SPU affinity

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>

Index: linux-2.6.22/arch/powerpc/platforms/cell/spufs/inode.c
===================================================================
--- linux-2.6.22.orig/arch/powerpc/platforms/cell/spufs/inode.c
+++ linux-2.6.22/arch/powerpc/platforms/cell/spufs/inode.c
@@ -320,7 +320,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;
 
@@ -352,11 +352,15 @@ spufs_assert_affinity(unsigned int flags
 		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)
@@ -370,11 +374,17 @@ spufs_assert_affinity(unsigned int flags
 				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
@@ -452,9 +462,12 @@ spufs_create_context(struct inode *inode
 	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