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>
compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
{
fd_set_bits fds;
compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
{
fd_set_bits fds;
int size, max_fds, ret = -EINVAL;
struct fdtable *fdt;
int size, max_fds, ret = -EINVAL;
struct fdtable *fdt;
+ long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
if (n < 0)
goto out_nofds;
if (n < 0)
goto out_nofds;
* since we used fdset we need to allocate memory in units of
* long-words.
*/
* since we used fdset we need to allocate memory in units of
* long-words.
*/
- 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);
fds.in = (unsigned long *) bits;
fds.out = (unsigned long *) (bits + size);
fds.ex = (unsigned long *) (bits + 2*size);
compat_set_fd_set(n, exp, fds.res_ex))
ret = -EFAULT;
out:
compat_set_fd_set(n, exp, fds.res_ex))
ret = -EFAULT;
out:
+ if (bits != stack_fds)
+ kfree(bits);