diff options
author | Dipankar Sarma <dipankar@in.ibm.com> | 2005-09-09 16:04:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:55 -0400 |
commit | b835996f628eadb55c5fb222ba46fe9395bf73c7 (patch) | |
tree | d63d80585d197e1ffc299af4a0034049790fb197 /fs/select.c | |
parent | ab2af1f5005069321c5d130f09cce577b03f43ef (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.c | 13 |
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(¤t->files->file_lock); | 189 | rcu_read_lock(); |
189 | retval = max_select_fd(n, fds); | 190 | retval = max_select_fd(n, fds); |
190 | spin_unlock(¤t->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) { |