aboutsummaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
authorDipankar Sarma <dipankar@in.ibm.com>2005-09-09 16:04:14 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:55 -0400
commitb835996f628eadb55c5fb222ba46fe9395bf73c7 (patch)
treed63d80585d197e1ffc299af4a0034049790fb197 /fs/select.c
parentab2af1f5005069321c5d130f09cce577b03f43ef (diff)
[PATCH] files: lock-free fd look-up
With the use of RCU in files structure, the look-up of files using fds can now be lock-free. The lookup is protected by rcu_read_lock()/rcu_read_unlock(). This patch changes the readers to use lock-free lookup. Signed-off-by: Maneesh Soni <maneesh@in.ibm.com> Signed-off-by: Ravikiran Thirumalai <kiran_th@gmail.com> Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/select.c b/fs/select.c
index 2e56325c73c4..f10a10317d54 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -22,6 +22,7 @@
22#include <linux/personality.h> /* for STICKY_TIMEOUTS */ 22#include <linux/personality.h> /* for STICKY_TIMEOUTS */
23#include <linux/file.h> 23#include <linux/file.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/rcupdate.h>
25 26
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
27 28
@@ -185,9 +186,9 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
185 int retval, i; 186 int retval, i;
186 long __timeout = *timeout; 187 long __timeout = *timeout;
187 188
188 spin_lock(&current->files->file_lock); 189 rcu_read_lock();
189 retval = max_select_fd(n, fds); 190 retval = max_select_fd(n, fds);
190 spin_unlock(&current->files->file_lock); 191 rcu_read_unlock();
191 192
192 if (retval < 0) 193 if (retval < 0)
193 return retval; 194 return retval;
@@ -329,8 +330,10 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
329 goto out_nofds; 330 goto out_nofds;
330 331
331 /* max_fdset can increase, so grab it once to avoid race */ 332 /* max_fdset can increase, so grab it once to avoid race */
333 rcu_read_lock();
332 fdt = files_fdtable(current->files); 334 fdt = files_fdtable(current->files);
333 max_fdset = fdt->max_fdset; 335 max_fdset = fdt->max_fdset;
336 rcu_read_unlock();
334 if (n > max_fdset) 337 if (n > max_fdset)
335 n = max_fdset; 338 n = max_fdset;
336 339
@@ -469,10 +472,14 @@ asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long ti
469 struct poll_list *head; 472 struct poll_list *head;
470 struct poll_list *walk; 473 struct poll_list *walk;
471 struct fdtable *fdt; 474 struct fdtable *fdt;
475 int max_fdset;
472 476
473 /* Do a sanity check on nfds ... */ 477 /* Do a sanity check on nfds ... */
478 rcu_read_lock();
474 fdt = files_fdtable(current->files); 479 fdt = files_fdtable(current->files);
475 if (nfds > fdt->max_fdset && nfds > OPEN_MAX) 480 max_fdset = fdt->max_fdset;
481 rcu_read_unlock();
482 if (nfds > max_fdset && nfds > OPEN_MAX)
476 return -EINVAL; 483 return -EINVAL;
477 484
478 if (timeout) { 485 if (timeout) {