Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=58119068cb27ef7513f80aff44b62a3a8f40ef5f
Commit:     58119068cb27ef7513f80aff44b62a3a8f40ef5f
Parent:     60cf54db47727935af1c439f59c636a96a8cbd4b
Author:     Andre Detsch <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 11 15:03:26 2008 +1100
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Wed Feb 6 16:26:59 2008 +1100

    [POWERPC] spufs: Fix memory leak on SPU affinity
    
    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 <[EMAIL PROTECTED]>
    Signed-off-by: Jeremy Kerr <[EMAIL PROTECTED]>
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/platforms/cell/spufs/inode.c |   29 +++++++++++++++++++++--------
 1 files 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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to