diff options
author | Badari Pulavarty <pbadari@us.ibm.com> | 2007-05-23 13:57:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-23 20:14:12 -0700 |
commit | 6087b2dab2c914268b1a50882edbbad82bfefd29 (patch) | |
tree | 3f286422a61e7e3206b4a0dba6cb7c18a09e6463 | |
parent | 7bb44adef39ad3bda2be40bb34686bc56bd563a5 (diff) |
optimize compat_core_sys_select() by a using stack space for small fd sets
Optimize select by a using stack space for small fd sets.
core_sys_select() already has this optimization. This is for compat
version.
Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/compat.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/compat.c b/fs/compat.c index 1de2331db844..4db6216e5266 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1544,9 +1544,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout) { fd_set_bits fds; - char *bits; + void *bits; int size, max_fds, ret = -EINVAL; struct fdtable *fdt; + long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; if (n < 0) goto out_nofds; @@ -1564,11 +1565,14 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, * since we used fdset we need to allocate memory in units of * long-words. */ - ret = -ENOMEM; size = FDS_BYTES(n); - bits = kmalloc(6 * size, GFP_KERNEL); - if (!bits) - goto out_nofds; + bits = stack_fds; + if (size > sizeof(stack_fds) / 6) { + bits = kmalloc(6 * size, GFP_KERNEL); + ret = -ENOMEM; + if (!bits) + goto out_nofds; + } fds.in = (unsigned long *) bits; fds.out = (unsigned long *) (bits + size); fds.ex = (unsigned long *) (bits + 2*size); @@ -1600,7 +1604,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, compat_set_fd_set(n, exp, fds.res_ex)) ret = -EFAULT; out: - kfree(bits); + if (bits != stack_fds) + kfree(bits); out_nofds: return ret; } |