aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/inode.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2005-11-15 15:53:52 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:49:30 -0500
commit8b3d6663c6217e4f50cc3720935a96da9b984117 (patch)
tree5295c29787ac66c26ddf715868fda7fcd3ad5f97 /arch/powerpc/platforms/cell/spufs/inode.c
parent05b841174c289ca62a6b42d883b8791d9ac3a4bd (diff)
[PATCH] spufs: cooperative scheduler support
This adds a scheduler for SPUs to make it possible to use more logical SPUs than physical ones are present in the system. Currently, there is no support for preempting a running SPU thread, they have to leave the SPU by either triggering an event on the SPU that causes it to return to the owning thread or by sending a signal to it. This patch also adds operations that enable accessing an SPU in either runnable or saved state. We use an RW semaphore to protect the state of the SPU from changing underneath us, while we are holding it readable. In order to change the state, it is acquired writeable and a context save or restore is executed before downgrading the semaphore to read-only. From: Mark Nutter <mnutter@us.ibm.com>, Uli Weigand <Ulrich.Weigand@de.ibm.com> Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/inode.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c62
1 files changed, 28 insertions, 34 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index f7aa0a6b1ce5..2c3ba4eb41cb 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -41,24 +41,6 @@
41 41
42static kmem_cache_t *spufs_inode_cache; 42static kmem_cache_t *spufs_inode_cache;
43 43
44/* Information about the backing dev, same as ramfs */
45#if 0
46static struct backing_dev_info spufs_backing_dev_info = {
47 .ra_pages = 0, /* No readahead */
48 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK |
49 BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | BDI_CAP_READ_MAP |
50 BDI_CAP_WRITE_MAP,
51};
52
53static struct address_space_operations spufs_aops = {
54 .readpage = simple_readpage,
55 .prepare_write = simple_prepare_write,
56 .commit_write = simple_commit_write,
57};
58#endif
59
60/* Inode operations */
61
62static struct inode * 44static struct inode *
63spufs_alloc_inode(struct super_block *sb) 45spufs_alloc_inode(struct super_block *sb)
64{ 46{
@@ -111,9 +93,6 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
111{ 93{
112 struct inode *inode = dentry->d_inode; 94 struct inode *inode = dentry->d_inode;
113 95
114/* dump_stack();
115 pr_debug("ia_size %lld, i_size:%lld\n", attr->ia_size, inode->i_size);
116*/
117 if ((attr->ia_valid & ATTR_SIZE) && 96 if ((attr->ia_valid & ATTR_SIZE) &&
118 (attr->ia_size != inode->i_size)) 97 (attr->ia_size != inode->i_size))
119 return -EINVAL; 98 return -EINVAL;
@@ -127,9 +106,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry,
127 struct spu_context *ctx) 106 struct spu_context *ctx)
128{ 107{
129 static struct inode_operations spufs_file_iops = { 108 static struct inode_operations spufs_file_iops = {
130 .getattr = simple_getattr,
131 .setattr = spufs_setattr, 109 .setattr = spufs_setattr,
132 .unlink = simple_unlink,
133 }; 110 };
134 struct inode *inode; 111 struct inode *inode;
135 int ret; 112 int ret;
@@ -183,21 +160,32 @@ out:
183 160
184static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) 161static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
185{ 162{
186 struct dentry *dentry; 163 struct dentry *dentry, *tmp;
164 struct spu_context *ctx;
187 int err; 165 int err;
188 166
189 spin_lock(&dcache_lock);
190 /* remove all entries */ 167 /* remove all entries */
191 err = 0; 168 err = 0;
192 list_for_each_entry(dentry, &dir_dentry->d_subdirs, d_child) { 169 list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) {
193 if (d_unhashed(dentry) || !dentry->d_inode) 170 spin_lock(&dcache_lock);
194 continue;
195 atomic_dec(&dentry->d_count);
196 spin_lock(&dentry->d_lock); 171 spin_lock(&dentry->d_lock);
197 __d_drop(dentry); 172 if (!(d_unhashed(dentry)) && dentry->d_inode) {
198 spin_unlock(&dentry->d_lock); 173 dget_locked(dentry);
174 __d_drop(dentry);
175 spin_unlock(&dentry->d_lock);
176 simple_unlink(dir_dentry->d_inode, dentry);
177 spin_unlock(&dcache_lock);
178 dput(dentry);
179 } else {
180 spin_unlock(&dentry->d_lock);
181 spin_unlock(&dcache_lock);
182 }
199 } 183 }
200 spin_unlock(&dcache_lock); 184
185 /* We have to give up the mm_struct */
186 ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
187 spu_forget(ctx);
188
201 if (!err) { 189 if (!err) {
202 shrink_dcache_parent(dir_dentry); 190 shrink_dcache_parent(dir_dentry);
203 err = simple_rmdir(root, dir_dentry); 191 err = simple_rmdir(root, dir_dentry);
@@ -249,7 +237,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
249 inode->i_gid = dir->i_gid; 237 inode->i_gid = dir->i_gid;
250 inode->i_mode &= S_ISGID; 238 inode->i_mode &= S_ISGID;
251 } 239 }
252 ctx = alloc_spu_context(); 240 ctx = alloc_spu_context(inode->i_mapping);
253 SPUFS_I(inode)->i_ctx = ctx; 241 SPUFS_I(inode)->i_ctx = ctx;
254 if (!ctx) 242 if (!ctx)
255 goto out_iput; 243 goto out_iput;
@@ -368,7 +356,8 @@ spufs_parse_options(char *options, struct inode *root)
368} 356}
369 357
370static int 358static int
371spufs_create_root(struct super_block *sb, void *data) { 359spufs_create_root(struct super_block *sb, void *data)
360{
372 struct inode *inode; 361 struct inode *inode;
373 int ret; 362 int ret;
374 363
@@ -441,6 +430,10 @@ static int spufs_init(void)
441 430
442 if (!spufs_inode_cache) 431 if (!spufs_inode_cache)
443 goto out; 432 goto out;
433 if (spu_sched_init() != 0) {
434 kmem_cache_destroy(spufs_inode_cache);
435 goto out;
436 }
444 ret = register_filesystem(&spufs_type); 437 ret = register_filesystem(&spufs_type);
445 if (ret) 438 if (ret)
446 goto out_cache; 439 goto out_cache;
@@ -459,6 +452,7 @@ module_init(spufs_init);
459 452
460static void spufs_exit(void) 453static void spufs_exit(void)
461{ 454{
455 spu_sched_exit();
462 unregister_spu_syscalls(&spufs_calls); 456 unregister_spu_syscalls(&spufs_calls);
463 unregister_filesystem(&spufs_type); 457 unregister_filesystem(&spufs_type);
464 kmem_cache_destroy(spufs_inode_cache); 458 kmem_cache_destroy(spufs_inode_cache);