Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67339
b: refs/heads/master
c: 98f0697
h: refs/heads/master
i:
  67337: 89977e0
  67335: 152f005
v: v3
  • Loading branch information
Jeremy Kerr authored and Paul Mackerras committed Sep 19, 2007
1 parent 06b70b8 commit c0dc09e
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 98 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 36ddbb1380f282b4280c57efdb646dd8647a789f
refs/heads/master: 98f06978ffebbec16abdea58489f217229580859
4 changes: 1 addition & 3 deletions trunk/arch/powerpc/platforms/cell/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o
endif

# needed only when building loadable spufs.ko
spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o

spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o
spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o

obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
spu_coredump.o \
$(spufs-modular-m) \
spu_coredump.o spu_syscalls.o \
$(spu-priv1-y) \
$(spu-manage-y) \
spufs/
Expand Down
108 changes: 68 additions & 40 deletions trunk/arch/powerpc/platforms/cell/spu_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,70 @@
#include <linux/file.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/rcupdate.h>

#include <asm/spu.h>

struct spufs_calls spufs_calls = {
.owner = NULL,
};
/* protected by rcu */
static struct spufs_calls *spufs_calls;

/* These stub syscalls are needed to have the actual implementation
* within a loadable module. When spufs is built into the kernel,
* this file is not used and the syscalls directly enter the fs code */
#ifdef CONFIG_SPU_FS_MODULE

static inline struct spufs_calls *spufs_calls_get(void)
{
struct spufs_calls *calls = NULL;

rcu_read_lock();
calls = rcu_dereference(spufs_calls);
if (calls && !try_module_get(calls->owner))
calls = NULL;
rcu_read_unlock();

return calls;
}

static inline void spufs_calls_put(struct spufs_calls *calls)
{
BUG_ON(calls != spufs_calls);

/* we don't need to rcu this, as we hold a reference to the module */
module_put(spufs_calls->owner);
}

#else /* !defined CONFIG_SPU_FS_MODULE */

static inline struct spufs_calls *spufs_calls_get(void)
{
return spufs_calls;
}

static inline void spufs_calls_put(struct spufs_calls *calls) { }

#endif /* CONFIG_SPU_FS_MODULE */

asmlinkage long sys_spu_create(const char __user *name,
unsigned int flags, mode_t mode, int neighbor_fd)
{
long ret;
struct module *owner = spufs_calls.owner;
struct file *neighbor;
int fput_needed;
struct spufs_calls *calls;

ret = -ENOSYS;
if (owner && try_module_get(owner)) {
if (flags & SPU_CREATE_AFFINITY_SPU) {
neighbor = fget_light(neighbor_fd, &fput_needed);
ret = -EBADF;
if (neighbor) {
ret = spufs_calls.create_thread(name, flags,
mode, neighbor);
fput_light(neighbor, fput_needed);
}
}
else {
ret = spufs_calls.create_thread(name, flags,
mode, NULL);
calls = spufs_calls_get();
if (!calls)
return -ENOSYS;

if (flags & SPU_CREATE_AFFINITY_SPU) {
ret = -EBADF;
neighbor = fget_light(neighbor_fd, &fput_needed);
if (neighbor) {
ret = calls->create_thread(name, flags, mode, neighbor);
fput_light(neighbor, fput_needed);
}
module_put(owner);
}
} else
ret = calls->create_thread(name, flags, mode, NULL);

spufs_calls_put(calls);
return ret;
}

Expand All @@ -66,37 +94,37 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
long ret;
struct file *filp;
int fput_needed;
struct module *owner = spufs_calls.owner;
struct spufs_calls *calls;

ret = -ENOSYS;
if (owner && try_module_get(owner)) {
ret = -EBADF;
filp = fget_light(fd, &fput_needed);
if (filp) {
ret = spufs_calls.spu_run(filp, unpc, ustatus);
fput_light(filp, fput_needed);
}
module_put(owner);
calls = spufs_calls_get();
if (!calls)
return -ENOSYS;

ret = -EBADF;
filp = fget_light(fd, &fput_needed);
if (filp) {
ret = calls->spu_run(filp, unpc, ustatus);
fput_light(filp, fput_needed);
}

spufs_calls_put(calls);
return ret;
}

int register_spu_syscalls(struct spufs_calls *calls)
{
if (spufs_calls.owner)
if (spufs_calls)
return -EBUSY;

spufs_calls.create_thread = calls->create_thread;
spufs_calls.spu_run = calls->spu_run;
smp_mb();
spufs_calls.owner = calls->owner;
rcu_assign_pointer(spufs_calls, calls);
return 0;
}
EXPORT_SYMBOL_GPL(register_spu_syscalls);

void unregister_spu_syscalls(struct spufs_calls *calls)
{
BUG_ON(spufs_calls.owner != calls->owner);
spufs_calls.owner = NULL;
BUG_ON(spufs_calls->owner != calls->owner);
rcu_assign_pointer(spufs_calls, NULL);
synchronize_rcu();
}
EXPORT_SYMBOL_GPL(unregister_spu_syscalls);
1 change: 1 addition & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/spufs.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ extern struct tree_descr spufs_dir_contents[];
extern struct tree_descr spufs_dir_nosched_contents[];

/* system call implementation */
extern struct spufs_calls spufs_calls;
long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
long spufs_create(struct nameidata *nd, unsigned int flags,
mode_t mode, struct file *filp);
Expand Down
42 changes: 0 additions & 42 deletions trunk/arch/powerpc/platforms/cell/spufs/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,6 @@ static long do_spu_run(struct file *filp,
return ret;
}

#ifndef MODULE
asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
{
int fput_needed;
struct file *filp;
long ret;

ret = -EBADF;
filp = fget_light(fd, &fput_needed);
if (filp) {
ret = do_spu_run(filp, unpc, ustatus);
fput_light(filp, fput_needed);
}

return ret;
}
#endif

static long do_spu_create(const char __user *pathname, unsigned int flags,
mode_t mode, struct file *neighbor)
{
Expand All @@ -99,30 +81,6 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
return ret;
}

#ifndef MODULE
asmlinkage long sys_spu_create(const char __user *pathname, unsigned int flags,
mode_t mode, int neighbor_fd)
{
int fput_needed;
struct file *neighbor;
long ret;

if (flags & SPU_CREATE_AFFINITY_SPU) {
ret = -EBADF;
neighbor = fget_light(neighbor_fd, &fput_needed);
if (neighbor) {
ret = do_spu_create(pathname, flags, mode, neighbor);
fput_light(neighbor, fput_needed);
}
}
else {
ret = do_spu_create(pathname, flags, mode, NULL);
}

return ret;
}
#endif

struct spufs_calls spufs_calls = {
.create_thread = do_spu_create,
.spu_run = do_spu_run,
Expand Down
14 changes: 2 additions & 12 deletions trunk/include/asm-powerpc/spu.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,14 @@ extern long spu_sys_callback(struct spu_syscall_block *s);

/* syscalls implemented in spufs */
struct file;
extern struct spufs_calls {
struct spufs_calls {
asmlinkage long (*create_thread)(const char __user *name,
unsigned int flags, mode_t mode,
struct file *neighbor);
asmlinkage long (*spu_run)(struct file *filp, __u32 __user *unpc,
__u32 __user *ustatus);
struct module *owner;
} spufs_calls;
};

/* coredump calls implemented in spufs */
struct spu_coredump_calls {
Expand Down Expand Up @@ -274,18 +274,8 @@ struct spu_coredump_calls {
#define SPU_CREATE_FLAG_ALL 0x003f /* mask of all valid flags */


#ifdef CONFIG_SPU_FS_MODULE
int register_spu_syscalls(struct spufs_calls *calls);
void unregister_spu_syscalls(struct spufs_calls *calls);
#else
static inline int register_spu_syscalls(struct spufs_calls *calls)
{
return 0;
}
static inline void unregister_spu_syscalls(struct spufs_calls *calls)
{
}
#endif /* MODULE */

int register_arch_coredump_calls(struct spu_coredump_calls *calls);
void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
Expand Down

0 comments on commit c0dc09e

Please sign in to comment.