2005-11-15 20:53:48 +00:00
|
|
|
/*
|
|
|
|
* SPU file system -- system call stubs
|
|
|
|
*
|
|
|
|
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
|
2007-09-19 04:38:12 +00:00
|
|
|
* (C) Copyright 2006-2007, IBM Corporation
|
2005-11-15 20:53:48 +00:00
|
|
|
*
|
|
|
|
* Author: Arnd Bergmann <arndb@de.ibm.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include <linux/file.h>
|
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.
Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.
Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.
Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.
We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.
It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
#include <linux/fs.h>
|
2005-11-15 20:53:48 +00:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/syscalls.h>
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
#include <linux/rcupdate.h>
|
2005-11-15 20:53:48 +00:00
|
|
|
|
|
|
|
#include <asm/spu.h>
|
|
|
|
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
/* protected by rcu */
|
|
|
|
static struct spufs_calls *spufs_calls;
|
2005-11-15 20:53:48 +00:00
|
|
|
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
#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 */
|
2005-11-15 20:53:48 +00:00
|
|
|
|
2011-07-26 20:50:23 +00:00
|
|
|
SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
|
|
|
|
umode_t, mode, int, neighbor_fd)
|
2005-11-15 20:53:48 +00:00
|
|
|
{
|
|
|
|
long ret;
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
struct spufs_calls *calls;
|
2005-11-15 20:53:48 +00:00
|
|
|
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
calls = spufs_calls_get();
|
|
|
|
if (!calls)
|
|
|
|
return -ENOSYS;
|
|
|
|
|
|
|
|
if (flags & SPU_CREATE_AFFINITY_SPU) {
|
2012-08-28 16:52:22 +00:00
|
|
|
struct fd neighbor = fdget(neighbor_fd);
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
ret = -EBADF;
|
2012-08-28 16:52:22 +00:00
|
|
|
if (neighbor.file) {
|
|
|
|
ret = calls->create_thread(name, flags, mode, neighbor.file);
|
|
|
|
fdput(neighbor);
|
2007-07-20 19:39:47 +00:00
|
|
|
}
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
} else
|
|
|
|
ret = calls->create_thread(name, flags, mode, NULL);
|
|
|
|
|
|
|
|
spufs_calls_put(calls);
|
2005-11-15 20:53:48 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
|
|
|
|
{
|
|
|
|
long ret;
|
2012-08-28 16:52:22 +00:00
|
|
|
struct fd arg;
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
struct spufs_calls *calls;
|
2005-11-15 20:53:48 +00:00
|
|
|
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
calls = spufs_calls_get();
|
|
|
|
if (!calls)
|
|
|
|
return -ENOSYS;
|
|
|
|
|
|
|
|
ret = -EBADF;
|
2012-08-28 16:52:22 +00:00
|
|
|
arg = fdget(fd);
|
|
|
|
if (arg.file) {
|
|
|
|
ret = calls->spu_run(arg.file, unpc, ustatus);
|
|
|
|
fdput(arg);
|
2005-11-15 20:53:48 +00:00
|
|
|
}
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
|
|
|
|
spufs_calls_put(calls);
|
2005-11-15 20:53:48 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.
Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.
Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.
Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.
We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.
It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
int elf_coredump_extra_notes_size(void)
|
2007-09-19 04:38:12 +00:00
|
|
|
{
|
|
|
|
struct spufs_calls *calls;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
calls = spufs_calls_get();
|
|
|
|
if (!calls)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ret = calls->coredump_extra_notes_size();
|
|
|
|
|
|
|
|
spufs_calls_put(calls);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.
Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.
Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.
Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.
We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.
It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset)
|
2007-09-19 04:38:12 +00:00
|
|
|
{
|
|
|
|
struct spufs_calls *calls;
|
2007-09-19 04:38:12 +00:00
|
|
|
int ret;
|
2007-09-19 04:38:12 +00:00
|
|
|
|
|
|
|
calls = spufs_calls_get();
|
|
|
|
if (!calls)
|
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.
Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.
Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.
Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.
We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.
It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
return 0;
|
2007-09-19 04:38:12 +00:00
|
|
|
|
2007-09-19 04:38:12 +00:00
|
|
|
ret = calls->coredump_extra_notes_write(file, foffset);
|
2007-09-19 04:38:12 +00:00
|
|
|
|
|
|
|
spufs_calls_put(calls);
|
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
To start with, arch_notes_size() etc. is a little too ambiguous a name for
my liking, so change the function names to be more explicit.
Calling through macros is ugly, especially with hidden parameters, so don't
do that, call the routines directly.
Use ARCH_HAVE_EXTRA_ELF_NOTES as the only flag, and based on it decide
whether we want the extern declarations or the empty versions.
Since we have empty routines, actually use them in the coredump code to
save a few #ifdefs.
We want to change the handling of foffset so that the write routine updates
foffset as it goes, instead of using file->f_pos (so that writing to a pipe
works). So pass foffset to the write routine, and for now just set it to
file->f_pos at the end of writing.
It should also be possible for the write routine to fail, so change it to
return int and treat a non-zero return as failure.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
|
2007-09-19 04:38:12 +00:00
|
|
|
return ret;
|
2007-09-19 04:38:12 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 14:27:30 +00:00
|
|
|
void notify_spus_active(void)
|
|
|
|
{
|
|
|
|
struct spufs_calls *calls;
|
|
|
|
|
|
|
|
calls = spufs_calls_get();
|
|
|
|
if (!calls)
|
|
|
|
return;
|
|
|
|
|
|
|
|
calls->notify_spus_active();
|
|
|
|
spufs_calls_put(calls);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-11-15 20:53:48 +00:00
|
|
|
int register_spu_syscalls(struct spufs_calls *calls)
|
|
|
|
{
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
if (spufs_calls)
|
2005-11-15 20:53:48 +00:00
|
|
|
return -EBUSY;
|
|
|
|
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
rcu_assign_pointer(spufs_calls, calls);
|
2005-11-15 20:53:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(register_spu_syscalls);
|
|
|
|
|
|
|
|
void unregister_spu_syscalls(struct spufs_calls *calls)
|
|
|
|
{
|
[POWERPC] cell: Unify spufs syscall path
At present, a built-in spufs will not use the spufs_calls callbacks, but
directly call sys_spu_create. This saves us an indirect branch, but
means we have duplicated functions - one for CONFIG_SPU_FS=y and one for
=m.
This change unifies the spufs syscall path, and provides access to the
spufs_calls structure through a get/put pair. At present, the only user
of the spufs_calls structure is spu_syscalls.c, but this will facilitate
adding the coredump calls later.
Everyone likes numbers, right? Here's a before/after comparison with
CONFIG_SPU_FS=y, doing spu_create(); close(); 64k times.
Before:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.075s
user 0m0.146s
sys 0m23.925s
After:
[jk@cell ~]$ time ./spu_create
performing 65536 spu_create calls
real 0m24.777s
user 0m0.141s
sys 0m24.631s
So, we're adding around 11us per syscall, at the benefit of having
only one syscall path.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2007-09-19 04:38:12 +00:00
|
|
|
BUG_ON(spufs_calls->owner != calls->owner);
|
|
|
|
rcu_assign_pointer(spufs_calls, NULL);
|
|
|
|
synchronize_rcu();
|
2005-11-15 20:53:48 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(unregister_spu_syscalls);
|