diff options
author | Badari Pulavarty <pbadari@us.ibm.com> | 2007-05-23 16:57:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-23 23:14:12 -0400 |
commit | 6087b2dab2c914268b1a50882edbbad82bfefd29 (patch) | |
tree | 3f286422a61e7e3206b4a0dba6cb7c18a09e6463 /fs | |
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>
Diffstat (limited to 'fs')
-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, | |||
1544 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout) | 1544 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout) |
1545 | { | 1545 | { |
1546 | fd_set_bits fds; | 1546 | fd_set_bits fds; |
1547 | char *bits; | 1547 | void *bits; |
1548 | int size, max_fds, ret = -EINVAL; | 1548 | int size, max_fds, ret = -EINVAL; |
1549 | struct fdtable *fdt; | 1549 | struct fdtable *fdt; |
1550 | long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; | ||
1550 | 1551 | ||
1551 | if (n < 0) | 1552 | if (n < 0) |
1552 | goto out_nofds; | 1553 | goto out_nofds; |
@@ -1564,11 +1565,14 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1564 | * since we used fdset we need to allocate memory in units of | 1565 | * since we used fdset we need to allocate memory in units of |
1565 | * long-words. | 1566 | * long-words. |
1566 | */ | 1567 | */ |
1567 | ret = -ENOMEM; | ||
1568 | size = FDS_BYTES(n); | 1568 | size = FDS_BYTES(n); |
1569 | bits = kmalloc(6 * size, GFP_KERNEL); | 1569 | bits = stack_fds; |
1570 | if (!bits) | 1570 | if (size > sizeof(stack_fds) / 6) { |
1571 | goto out_nofds; | 1571 | bits = kmalloc(6 * size, GFP_KERNEL); |
1572 | ret = -ENOMEM; | ||
1573 | if (!bits) | ||
1574 | goto out_nofds; | ||
1575 | } | ||
1572 | fds.in = (unsigned long *) bits; | 1576 | fds.in = (unsigned long *) bits; |
1573 | fds.out = (unsigned long *) (bits + size); | 1577 | fds.out = (unsigned long *) (bits + size); |
1574 | fds.ex = (unsigned long *) (bits + 2*size); | 1578 | fds.ex = (unsigned long *) (bits + 2*size); |
@@ -1600,7 +1604,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1600 | compat_set_fd_set(n, exp, fds.res_ex)) | 1604 | compat_set_fd_set(n, exp, fds.res_ex)) |
1601 | ret = -EFAULT; | 1605 | ret = -EFAULT; |
1602 | out: | 1606 | out: |
1603 | kfree(bits); | 1607 | if (bits != stack_fds) |
1608 | kfree(bits); | ||
1604 | out_nofds: | 1609 | out_nofds: |
1605 | return ret; | 1610 | return ret; |
1606 | } | 1611 | } |