diff options
author | Dipankar Sarma <dipankar@in.ibm.com> | 2005-09-09 16:04:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:55 -0400 |
commit | ab2af1f5005069321c5d130f09cce577b03f43ef (patch) | |
tree | 73a70ba486f522cd9eeeef376ede2b5a1c1b473b /kernel/exit.c | |
parent | 6e72ad2c581de121cc7e772469e2a8f6b1fd4379 (diff) |
[PATCH] files: files struct with RCU
Patch to eliminate struct files_struct.file_lock spinlock on the reader side
and use rcu refcounting rcuref_xxx api for the f_count refcounter. The
updates to the fdtable are done by allocating a new fdtable structure and
setting files->fdt to point to the new structure. The fdtable structure is
protected by RCU thereby allowing lock-free lookup. For fd arrays/sets that
are vmalloced, we use keventd to free them since RCU callbacks can't sleep. A
global list of fdtable to be freed is not scalable, so we use a per-cpu list.
If keventd is already handling the current cpu's work, we use a timer to defer
queueing of that work.
Since the last publication, this patch has been re-written to avoid using
explicit memory barriers and use rcu_assign_pointer(), rcu_dereference()
premitives instead. This required that the fd information is kept in a
separate structure (fdtable) and updated atomically.
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 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 83beb1e93b18..6d2089a1bce7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -411,15 +411,16 @@ void fastcall put_files_struct(struct files_struct *files) | |||
411 | close_files(files); | 411 | close_files(files); |
412 | /* | 412 | /* |
413 | * Free the fd and fdset arrays if we expanded them. | 413 | * Free the fd and fdset arrays if we expanded them. |
414 | * If the fdtable was embedded, pass files for freeing | ||
415 | * at the end of the RCU grace period. Otherwise, | ||
416 | * you can free files immediately. | ||
414 | */ | 417 | */ |
415 | fdt = files_fdtable(files); | 418 | fdt = files_fdtable(files); |
416 | if (fdt->fd != &files->fd_array[0]) | 419 | if (fdt == &files->fdtab) |
417 | free_fd_array(fdt->fd, fdt->max_fds); | 420 | fdt->free_files = files; |
418 | if (fdt->max_fdset > __FD_SETSIZE) { | 421 | else |
419 | free_fdset(fdt->open_fds, fdt->max_fdset); | 422 | kmem_cache_free(files_cachep, files); |
420 | free_fdset(fdt->close_on_exec, fdt->max_fdset); | 423 | free_fdtable(fdt); |
421 | } | ||
422 | kmem_cache_free(files_cachep, files); | ||
423 | } | 424 | } |
424 | } | 425 | } |
425 | 426 | ||