lkml.org 
[lkml]   [2006]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC, PATCH] avoid some atomics in open()/close() for monothreaded processes
    Goal : Avoid some locking/unlocking 'struct files_struct'->file_lock for mono 
    threaded processes.

    We define files_multithreaded() function .

    static inline int files_multithreaded(const struct files_struct *files)
    {
    return sizeof(files->file_lock) > 0 && atomic_read(&files->count) > 1;
    }

    On plain UP kernel (not preemptable nor spinlock debug), this function is a
    const 0, so that gcc can wipe out some code.

    On preemptible or SMP, or spinlock debug kernels, the result is true only if
    the ref count is greater than 1 (multi threaded process or /proc/{pid}/fd is
    under investigation by another task)

    This patch increases kernel size but pros are worth the cons, as said Linus
    himself, we should increase performance of mono-threaded tasks....

    Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
    --- a/include/linux/file.h 2006-03-22 06:23:02.000000000 +0100
    +++ b/include/linux/file.h 2006-03-22 07:11:08.000000000 +0100
    @@ -42,6 +42,11 @@
    spinlock_t file_lock; /* Protects concurrent writers. Nests inside tsk->alloc_lock */
    };

    +static inline int files_multithreaded(const struct files_struct *files)
    +{
    + return sizeof(files->file_lock) > 0 && atomic_read(&files->count) > 1;
    +}
    +
    #define files_fdtable(files) (rcu_dereference((files)->fdt))

    extern void FASTCALL(__fput(struct file *));
    --- a/fs/open.c.orig 2006-03-22 06:24:34.000000000 +0100
    +++ b/fs/open.c 2006-03-22 06:30:54.000000000 +0100
    @@ -1050,11 +1050,17 @@
    {
    struct files_struct *files = current->files;
    struct fdtable *fdt;
    - spin_lock(&files->file_lock);
    + int fl_locked = 0;
    +
    + if (files_multithreaded(files)) {
    + spin_lock(&files->file_lock);
    + fl_locked = 1;
    + }
    fdt = files_fdtable(files);
    BUG_ON(fdt->fd[fd] != NULL);
    rcu_assign_pointer(fdt->fd[fd], file);
    - spin_unlock(&files->file_lock);
    + if (fl_locked)
    + spin_unlock(&files->file_lock);
    }

    EXPORT_SYMBOL(fd_install);
    @@ -1147,8 +1153,12 @@
    struct file * filp;
    struct files_struct *files = current->files;
    struct fdtable *fdt;
    + int fl_locked = 0;

    - spin_lock(&files->file_lock);
    + if (files_multithreaded(files)) {
    + spin_lock(&files->file_lock);
    + fl_locked = 1;
    + }
    fdt = files_fdtable(files);
    if (fd >= fdt->max_fds)
    goto out_unlock;
    @@ -1158,11 +1168,13 @@
    rcu_assign_pointer(fdt->fd[fd], NULL);
    FD_CLR(fd, fdt->close_on_exec);
    __put_unused_fd(files, fd);
    - spin_unlock(&files->file_lock);
    + if (fl_locked)
    + spin_unlock(&files->file_lock);
    return filp_close(filp, files);

    out_unlock:
    - spin_unlock(&files->file_lock);
    + if (fl_locked)
    + spin_unlock(&files->file_lock);
    return -EBADF;
    }
    \
     
     \ /
      Last update: 2006-03-22 07:26    [W:0.028 / U:121.820 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site