]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] convert file_lock to a spinlock
authorAndrew Morton <akpm@digeo.com>
Sat, 12 Apr 2003 19:56:37 +0000 (12:56 -0700)
committerJames Bottomley <jejb@raven.il.steeleye.com>
Sat, 12 Apr 2003 19:56:37 +0000 (12:56 -0700)
Time to write a 2M file, one byte at a time:

Before:
        1.09s user 4.92s system 99% cpu 6.014 total
        0.74s user 5.28s system 99% cpu 6.023 total
        1.03s user 4.97s system 100% cpu 5.991 total

After:
0.79s user 5.17s system 99% cpu 5.993 total
0.79s user 5.17s system 100% cpu 5.957 total
0.84s user 5.11s system 100% cpu 5.942 total

drivers/char/tty_io.c
fs/exec.c
fs/fcntl.c
fs/file.c
fs/file_table.c
fs/open.c
fs/proc/base.c
fs/select.c
include/linux/file.h
include/linux/init_task.h
kernel/fork.c

index 90be7274e0ff9452f16926fac592165bec544d72..0a5814f00f37207cc4ae764257ea3f82887aff5a 100644 (file)
@@ -1874,7 +1874,7 @@ static void __do_SAK(void *arg)
                }
                task_lock(p);
                if (p->files) {
-                       read_lock(&p->files->file_lock);
+                       spin_lock(&p->files->file_lock);
                        for (i=0; i < p->files->max_fds; i++) {
                                filp = fcheck_files(p->files, i);
                                if (filp && (filp->f_op == &tty_fops) &&
@@ -1886,7 +1886,7 @@ static void __do_SAK(void *arg)
                                        break;
                                }
                        }
-                       read_unlock(&p->files->file_lock);
+                       spin_unlock(&p->files->file_lock);
                }
                task_unlock(p);
        }
index e3d434aa3a8f7d5d595cd57239d0ab92f0a066c0..cf9842394ea3f68f4be3f6dd7ad49ad0b881ac33 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -749,7 +749,7 @@ static inline void flush_old_files(struct files_struct * files)
 {
        long j = -1;
 
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        for (;;) {
                unsigned long set, i;
 
@@ -761,16 +761,16 @@ static inline void flush_old_files(struct files_struct * files)
                if (!set)
                        continue;
                files->close_on_exec->fds_bits[j] = 0;
-               write_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                for ( ; set ; i++,set >>= 1) {
                        if (set & 1) {
                                sys_close(i);
                        }
                }
-               write_lock(&files->file_lock);
+               spin_lock(&files->file_lock);
 
        }
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 }
 
 int flush_old_exec(struct linux_binprm * bprm)
index f1bf41ec99a55d0cb8fd38c55f78811835073144..0692a5948bf5648638d655f31a4ae20161af4300 100644 (file)
@@ -23,21 +23,21 @@ extern int fcntl_getlease(struct file *filp);
 void set_close_on_exec(unsigned int fd, int flag)
 {
        struct files_struct *files = current->files;
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (flag)
                FD_SET(fd, files->close_on_exec);
        else
                FD_CLR(fd, files->close_on_exec);
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 }
 
 static inline int get_close_on_exec(unsigned int fd)
 {
        struct files_struct *files = current->files;
        int res;
-       read_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        res = FD_ISSET(fd, files->close_on_exec);
-       read_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        return res;
 }
 
@@ -134,15 +134,15 @@ static int dupfd(struct file *file, int start)
        struct files_struct * files = current->files;
        int fd;
 
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        fd = locate_fd(files, file, start);
        if (fd >= 0) {
                FD_SET(fd, files->open_fds);
                FD_CLR(fd, files->close_on_exec);
-               write_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                fd_install(fd, file);
        } else {
-               write_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                fput(file);
        }
 
@@ -155,7 +155,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
        struct file * file, *tofree;
        struct files_struct * files = current->files;
 
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (!(file = fcheck(oldfd)))
                goto out_unlock;
        err = newfd;
@@ -186,7 +186,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
        files->fd[newfd] = file;
        FD_SET(newfd, files->open_fds);
        FD_CLR(newfd, files->close_on_exec);
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 
        if (tofree)
                filp_close(tofree, files);
@@ -194,11 +194,11 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
 out:
        return err;
 out_unlock:
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        goto out;
 
 out_fput:
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        fput(file);
        goto out;
 }
index 0ca7849d802959fa5bfec4d84819b7ecf8bc3822..e97f3a867b51358dfc52a9e13bad50265b97a90e 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -65,7 +65,7 @@ int expand_fd_array(struct files_struct *files, int nr)
                goto out;
 
        nfds = files->max_fds;
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 
        /* 
         * Expand to the max in easy steps, and keep expanding it until
@@ -89,7 +89,7 @@ int expand_fd_array(struct files_struct *files, int nr)
 
        error = -ENOMEM;
        new_fds = alloc_fd_array(nfds);
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (!new_fds)
                goto out;
 
@@ -110,15 +110,15 @@ int expand_fd_array(struct files_struct *files, int nr)
                        memset(&new_fds[i], 0,
                               (nfds-i) * sizeof(struct file *)); 
 
-                       write_unlock(&files->file_lock);
+                       spin_unlock(&files->file_lock);
                        free_fd_array(old_fds, i);
-                       write_lock(&files->file_lock);
+                       spin_lock(&files->file_lock);
                }
        } else {
                /* Somebody expanded the array while we slept ... */
-               write_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                free_fd_array(new_fds, nfds);
-               write_lock(&files->file_lock);
+               spin_lock(&files->file_lock);
        }
        error = 0;
 out:
@@ -167,7 +167,7 @@ int expand_fdset(struct files_struct *files, int nr)
                goto out;
 
        nfds = files->max_fdset;
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 
        /* Expand to the max in easy steps */
        do {
@@ -183,7 +183,7 @@ int expand_fdset(struct files_struct *files, int nr)
        error = -ENOMEM;
        new_openset = alloc_fdset(nfds);
        new_execset = alloc_fdset(nfds);
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (!new_openset || !new_execset)
                goto out;
 
@@ -208,21 +208,21 @@ int expand_fdset(struct files_struct *files, int nr)
                nfds = xchg(&files->max_fdset, nfds);
                new_openset = xchg(&files->open_fds, new_openset);
                new_execset = xchg(&files->close_on_exec, new_execset);
-               write_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                free_fdset (new_openset, nfds);
                free_fdset (new_execset, nfds);
-               write_lock(&files->file_lock);
+               spin_lock(&files->file_lock);
                return 0;
        } 
        /* Somebody expanded the array while we slept ... */
 
 out:
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        if (new_openset)
                free_fdset(new_openset, nfds);
        if (new_execset)
                free_fdset(new_execset, nfds);
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        return error;
 }
 
index 8ae8d29c2365597de486203573aedcb34acdc567..526c0dabc7b1d2da11bfdd0af921148fe1f333ea 100644 (file)
@@ -182,11 +182,11 @@ struct file *fget(unsigned int fd)
        struct file *file;
        struct files_struct *files = current->files;
 
-       read_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        file = fcheck(fd);
        if (file)
                get_file(file);
-       read_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        return file;
 }
 
index d56d61efe533a1b45ec34e9a0dfa4de32424df30..b3b15f1b2a1ec1c28bc0c4ae974ff62f6cf99355 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -702,7 +702,7 @@ int get_unused_fd(void)
        int fd, error;
 
        error = -EMFILE;
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
 
 repeat:
        fd = find_next_zero_bit(files->open_fds->fds_bits, 
@@ -751,7 +751,7 @@ repeat:
        error = fd;
 
 out:
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        return error;
 }
 
@@ -765,9 +765,9 @@ static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
 void put_unused_fd(unsigned int fd)
 {
        struct files_struct *files = current->files;
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        __put_unused_fd(files, fd);
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 }
 
 /*
@@ -786,11 +786,11 @@ void put_unused_fd(unsigned int fd)
 void fd_install(unsigned int fd, struct file * file)
 {
        struct files_struct *files = current->files;
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (unlikely(files->fd[fd] != NULL))
                BUG();
        files->fd[fd] = file;
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
 }
 
 asmlinkage long sys_open(const char __user * filename, int flags, int mode)
@@ -870,7 +870,7 @@ asmlinkage long sys_close(unsigned int fd)
        struct file * filp;
        struct files_struct *files = current->files;
 
-       write_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        if (fd >= files->max_fds)
                goto out_unlock;
        filp = files->fd[fd];
@@ -879,11 +879,11 @@ asmlinkage long sys_close(unsigned int fd)
        files->fd[fd] = NULL;
        FD_CLR(fd, files->close_on_exec);
        __put_unused_fd(files, fd);
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        return filp_close(filp, files);
 
 out_unlock:
-       write_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        return -EBADF;
 }
 
index c72b512876ec8e127143f49f961e541d2c2665d1..06e363b4efc8488d72fe322eef83a33f437fad25 100644 (file)
@@ -117,16 +117,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
                atomic_inc(&files->count);
        task_unlock(task);
        if (files) {
-               read_lock(&files->file_lock);
+               spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                if (file) {
                        *mnt = mntget(file->f_vfsmnt);
                        *dentry = dget(file->f_dentry);
-                       read_unlock(&files->file_lock);
+                       spin_unlock(&files->file_lock);
                        put_files_struct(files);
                        return 0;
                }
-               read_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                put_files_struct(files);
        }
        return -ENOENT;
@@ -655,7 +655,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
                        task_unlock(p);
                        if (!files)
                                goto out;
-                       read_lock(&files->file_lock);
+                       spin_lock(&files->file_lock);
                        for (fd = filp->f_pos-2;
                             fd < files->max_fds;
                             fd++, filp->f_pos++) {
@@ -663,7 +663,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
 
                                if (!fcheck_files(files, fd))
                                        continue;
-                               read_unlock(&files->file_lock);
+                               spin_unlock(&files->file_lock);
 
                                j = NUMBUF;
                                i = fd;
@@ -675,12 +675,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
 
                                ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
                                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
-                                       read_lock(&files->file_lock);
+                                       spin_lock(&files->file_lock);
                                        break;
                                }
-                               read_lock(&files->file_lock);
+                               spin_lock(&files->file_lock);
                        }
-                       read_unlock(&files->file_lock);
+                       spin_unlock(&files->file_lock);
                        put_files_struct(files);
        }
 out:
@@ -824,13 +824,13 @@ static int pid_fd_revalidate(struct dentry * dentry, int flags)
                atomic_inc(&files->count);
        task_unlock(task);
        if (files) {
-               read_lock(&files->file_lock);
+               spin_lock(&files->file_lock);
                if (fcheck_files(files, fd)) {
-                       read_unlock(&files->file_lock);
+                       spin_unlock(&files->file_lock);
                        put_files_struct(files);
                        return 1;
                }
-               read_unlock(&files->file_lock);
+               spin_unlock(&files->file_lock);
                put_files_struct(files);
        }
        d_drop(dentry);
@@ -920,7 +920,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
        if (!files)
                goto out_unlock;
        inode->i_mode = S_IFLNK;
-       read_lock(&files->file_lock);
+       spin_lock(&files->file_lock);
        file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock2;
@@ -928,7 +928,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
                inode->i_mode |= S_IRUSR | S_IXUSR;
        if (file->f_mode & 2)
                inode->i_mode |= S_IWUSR | S_IXUSR;
-       read_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        put_files_struct(files);
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
@@ -940,7 +940,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
        return NULL;
 
 out_unlock2:
-       read_unlock(&files->file_lock);
+       spin_unlock(&files->file_lock);
        put_files_struct(files);
 out_unlock:
        iput(inode);
index 455eaccaa7338f0fb698d1c9936cdd33b9ce41d8..631d41bea36e45775676e69ebd0c252bd0922669 100644 (file)
@@ -179,9 +179,9 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
        int retval, i, off;
        long __timeout = *timeout;
 
-       read_lock(&current->files->file_lock);
+       spin_lock(&current->files->file_lock);
        retval = max_select_fd(n, fds);
-       read_unlock(&current->files->file_lock);
+       spin_unlock(&current->files->file_lock);
 
        if (retval < 0)
                return retval;
index 0bfe318d873b9c58378a163ecd24cad25ebe9d16..6fbd27f755d5bf64aa69ec18c99c846eab0236e9 100644 (file)
@@ -21,7 +21,7 @@
  */
 struct files_struct {
         atomic_t count;
-        rwlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
+        spinlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
         int max_fds;
         int max_fdset;
         int next_fd;
index 6e749b6c5a7f77538d0d9342950f3ecb3ed9cbe8..96a5f926300e2fd348c97829150b4a7d9273868c 100644 (file)
@@ -6,7 +6,7 @@
 #define INIT_FILES \
 {                                                      \
        .count          = ATOMIC_INIT(1),               \
-       .file_lock      = RW_LOCK_UNLOCKED,             \
+       .file_lock      = SPIN_LOCK_UNLOCKED,           \
        .max_fds        = NR_OPEN_DEFAULT,              \
        .max_fdset      = __FD_SETSIZE,                 \
        .next_fd        = 0,                            \
index fececf441ae5571783ed5cd50a86b15ee48eedb9..c8b8b00c031d1e4c718c4a119ff71377fea2fab4 100644 (file)
@@ -603,7 +603,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
 
        atomic_set(&newf->count, 1);
 
-       newf->file_lock     = RW_LOCK_UNLOCKED;
+       newf->file_lock     = SPIN_LOCK_UNLOCKED;
        newf->next_fd       = 0;
        newf->max_fds       = NR_OPEN_DEFAULT;
        newf->max_fdset     = __FD_SETSIZE;
@@ -616,13 +616,13 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
        size = oldf->max_fdset;
        if (size > __FD_SETSIZE) {
                newf->max_fdset = 0;
-               write_lock(&newf->file_lock);
+               spin_lock(&newf->file_lock);
                error = expand_fdset(newf, size-1);
-               write_unlock(&newf->file_lock);
+               spin_unlock(&newf->file_lock);
                if (error)
                        goto out_release;
        }
-       read_lock(&oldf->file_lock);
+       spin_lock(&oldf->file_lock);
 
        open_files = count_open_files(oldf, size);
 
@@ -633,15 +633,15 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
         */
        nfds = NR_OPEN_DEFAULT;
        if (open_files > nfds) {
-               read_unlock(&oldf->file_lock);
+               spin_unlock(&oldf->file_lock);
                newf->max_fds = 0;
-               write_lock(&newf->file_lock);
+               spin_lock(&newf->file_lock);
                error = expand_fd_array(newf, open_files-1);
-               write_unlock(&newf->file_lock);
+               spin_unlock(&newf->file_lock);
                if (error) 
                        goto out_release;
                nfds = newf->max_fds;
-               read_lock(&oldf->file_lock);
+               spin_lock(&oldf->file_lock);
        }
 
        old_fds = oldf->fd;
@@ -656,7 +656,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
                        get_file(f);
                *new_fds++ = f;
        }
-       read_unlock(&oldf->file_lock);
+       spin_unlock(&oldf->file_lock);
 
        /* compute the remainder to be cleared */
        size = (newf->max_fds - open_files) * sizeof(struct file *);