diff options
author | Arnd Bergmann <arnd@arndb.de> | 2005-11-15 15:53:52 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 22:49:30 -0500 |
commit | 8b3d6663c6217e4f50cc3720935a96da9b984117 (patch) | |
tree | 5295c29787ac66c26ddf715868fda7fcd3ad5f97 /arch/powerpc/platforms/cell/spufs/inode.c | |
parent | 05b841174c289ca62a6b42d883b8791d9ac3a4bd (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.c | 62 |
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 | ||
42 | static kmem_cache_t *spufs_inode_cache; | 42 | static kmem_cache_t *spufs_inode_cache; |
43 | 43 | ||
44 | /* Information about the backing dev, same as ramfs */ | ||
45 | #if 0 | ||
46 | static 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 | |||
53 | static 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 | |||
62 | static struct inode * | 44 | static struct inode * |
63 | spufs_alloc_inode(struct super_block *sb) | 45 | spufs_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 | ||
184 | static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) | 161 | static 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 | ||
370 | static int | 358 | static int |
371 | spufs_create_root(struct super_block *sb, void *data) { | 359 | spufs_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 | ||
460 | static void spufs_exit(void) | 453 | static 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); |