Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=17e0e27020d028a790d97699aff85a43af5be472
Commit:     17e0e27020d028a790d97699aff85a43af5be472
Parent:     44430e0d3916ab6aaf0451fdb811f4f1803b741e
Author:     Benjamin Herrenschmidt <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 13 11:46:08 2007 +1100
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Tue Feb 13 15:35:54 2007 +1100

    [POWERPC] spufs: Fix bitrot of the SPU mmap facility
    
    It looks like we've had some serious bitrot there mostly due to tracking
    of address_space's of mmap'ed files getting out of sync with the actual
    mmap code. The mfc, mss and psmap were not tracked properly and thus
    not invalidated on context switches (oops !)
    
    I also removed the various file->f_mapping = inode->i_mapping;
    assignments that were done in the other open() routines since that
    is already done for us by __dentry_open.
    
    One improvement we might want to do later is to assign the various
    ctx-> fields at mmap time instead of file open/close time so that we
    don't call unmap_mapping_range() on thing that have not been mmap'ed
    
    Finally, I added some smp_wmb's after assigning the ctx-> fields to make
    sure they are visible to other CPUs. I don't think this is really
    necessary as I suspect locking in the fs layer will make that happen
    anyway but better safe than sorry.
    
    Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]>
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/platforms/cell/spufs/context.c |   12 ++++++++----
 arch/powerpc/platforms/cell/spufs/file.c    |   16 ++++++++++++----
 arch/powerpc/platforms/cell/spufs/spufs.h   |    2 ++
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/context.c 
b/arch/powerpc/platforms/cell/spufs/context.c
index 0870009..28c718c 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -111,13 +111,17 @@ 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, 0x4000, 1);
+               unmap_mapping_range(ctx->mfc, 0, 0x1000, 1);
        if (ctx->cntl)
-               unmap_mapping_range(ctx->cntl, 0, 0x4000, 1);
+               unmap_mapping_range(ctx->cntl, 0, 0x1000, 1);
        if (ctx->signal1)
-               unmap_mapping_range(ctx->signal1, 0, 0x4000, 1);
+               unmap_mapping_range(ctx->signal1, 0, PAGE_SIZE, 1);
        if (ctx->signal2)
-               unmap_mapping_range(ctx->signal2, 0, 0x4000, 1);
+               unmap_mapping_range(ctx->signal2, 0, PAGE_SIZE, 1);
+       if (ctx->mss)
+               unmap_mapping_range(ctx->mss, 0, 0x1000, 1);
+       if (ctx->psmap)
+               unmap_mapping_range(ctx->psmap, 0, 0x20000, 1);
 }
 
 int spu_acquire_exclusive(struct spu_context *ctx)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c 
b/arch/powerpc/platforms/cell/spufs/file.c
index 7fb9a6d..a528020 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -45,8 +45,8 @@ spufs_mem_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
        file->private_data = ctx;
-       file->f_mapping = inode->i_mapping;
        ctx->local_store = inode->i_mapping;
+       smp_wmb();
        return 0;
 }
 
@@ -232,8 +232,8 @@ static int spufs_cntl_open(struct inode *inode, struct file 
*file)
        struct spu_context *ctx = i->i_ctx;
 
        file->private_data = ctx;
-       file->f_mapping = inode->i_mapping;
        ctx->cntl = inode->i_mapping;
+       smp_wmb();
        return simple_attr_open(inode, file, spufs_cntl_get,
                                        spufs_cntl_set, "0x%08lx");
 }
@@ -717,8 +717,8 @@ static int spufs_signal1_open(struct inode *inode, struct 
file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
        file->private_data = ctx;
-       file->f_mapping = inode->i_mapping;
        ctx->signal1 = inode->i_mapping;
+       smp_wmb();
        return nonseekable_open(inode, file);
 }
 
@@ -824,8 +824,8 @@ static int spufs_signal2_open(struct inode *inode, struct 
file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
        file->private_data = ctx;
-       file->f_mapping = inode->i_mapping;
        ctx->signal2 = inode->i_mapping;
+       smp_wmb();
        return nonseekable_open(inode, file);
 }
 
@@ -1021,8 +1021,11 @@ static int spufs_mss_mmap(struct file *file, struct 
vm_area_struct *vma)
 static int spufs_mss_open(struct inode *inode, struct file *file)
 {
        struct spufs_inode_info *i = SPUFS_I(inode);
+       struct spu_context *ctx = i->i_ctx;
 
        file->private_data = i->i_ctx;
+       ctx->mss = inode->i_mapping;
+       smp_wmb();
        return nonseekable_open(inode, file);
 }
 
@@ -1060,8 +1063,11 @@ static int spufs_psmap_mmap(struct file *file, struct 
vm_area_struct *vma)
 static int spufs_psmap_open(struct inode *inode, struct file *file)
 {
        struct spufs_inode_info *i = SPUFS_I(inode);
+       struct spu_context *ctx = i->i_ctx;
 
        file->private_data = i->i_ctx;
+       ctx->psmap = inode->i_mapping;
+       smp_wmb();
        return nonseekable_open(inode, file);
 }
 
@@ -1114,6 +1120,8 @@ static int spufs_mfc_open(struct inode *inode, struct 
file *file)
                return -EBUSY;
 
        file->private_data = ctx;
+       ctx->mfc = inode->i_mapping;
+       smp_wmb();
        return nonseekable_open(inode, file);
 }
 
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h 
b/arch/powerpc/platforms/cell/spufs/spufs.h
index 5686446..0941c56 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -51,6 +51,8 @@ struct spu_context {
        struct address_space *cntl;        /* 'control' area mappings. */
        struct address_space *signal1;     /* 'signal1' area mappings. */
        struct address_space *signal2;     /* 'signal2' area mappings. */
+       struct address_space *mss;         /* 'mss' area mappings. */
+       struct address_space *psmap;       /* 'psmap' area mappings. */
        u64 object_id;             /* user space pointer for oprofile */
 
        enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
-
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