[patch-2.3.99-pre9-2] fs/exec.c optimizations

From: Tigran Aivazian (tigran@veritas.com)
Date: Tue May 16 2000 - 07:03:03 EST


Hi Linus,

This patch does two things to fs/exec.c:

a) sys_uselib() doesn't need lock/unlock_kernel as it uses
   sys_open() which protects the call to filp_open() via global kernel
   lock. I could probably make sys_uselib() use
   filp_open()/filp_close() without any need to use descriptors
   internally but doing so would make it more sensitive to VFS internals
   which is not a good idea.

b) binfmt_lock should be read/write lock and not a plain spinlock
   because only register/unregister_binfmt need to be mutually exclusive -
   the rest can happen concurrently.

Regards,
Tigran

--- linux/fs/exec.c Tue May 16 10:18:48 2000
+++ work/fs/exec.c Tue May 16 12:44:15 2000
@@ -46,7 +46,7 @@
 #endif
 
 static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
-static spinlock_t binfmt_lock = SPIN_LOCK_UNLOCKED;
+static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
 
 int register_binfmt(struct linux_binfmt * fmt)
 {
@@ -56,17 +56,17 @@
                 return -EINVAL;
         if (fmt->next)
                 return -EBUSY;
- spin_lock(&binfmt_lock);
+ write_lock(&binfmt_lock);
         while (*tmp) {
                 if (fmt == *tmp) {
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
                         return -EBUSY;
                 }
                 tmp = &(*tmp)->next;
         }
         fmt->next = formats;
         formats = fmt;
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
         return 0;
 }
 
@@ -74,16 +74,16 @@
 {
         struct linux_binfmt ** tmp = &formats;
 
- spin_lock(&binfmt_lock);
+ write_lock(&binfmt_lock);
         while (*tmp) {
                 if (fmt == *tmp) {
                         *tmp = fmt->next;
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
                         return 0;
                 }
                 tmp = &(*tmp)->next;
         }
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
         return -EINVAL;
 }
 
@@ -105,33 +105,29 @@
         struct file * file;
         struct linux_binfmt * fmt;
 
- lock_kernel();
         fd = sys_open(library, 0, 0);
- retval = fd;
         if (fd < 0)
- goto out;
+ return fd;
         file = fget(fd);
         retval = -ENOEXEC;
         if (file && file->f_op && file->f_op->read) {
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
                 for (fmt = formats ; fmt ; fmt = fmt->next) {
                         if (!fmt->load_shlib)
                                 continue;
                         if (!try_inc_mod_count(fmt->module))
                                 continue;
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
                         retval = fmt->load_shlib(file);
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
                         put_binfmt(fmt);
                         if (retval != -ENOEXEC)
                                 break;
                 }
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
         }
         fput(file);
         sys_close(fd);
-out:
- unlock_kernel();
           return retval;
 }
 
@@ -747,14 +743,14 @@
         }
 #endif
         for (try=0; try<2; try++) {
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
                 for (fmt = formats ; fmt ; fmt = fmt->next) {
                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
                         if (!fn)
                                 continue;
                         if (!try_inc_mod_count(fmt->module))
                                 continue;
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
                         retval = fn(bprm, regs);
                         if (retval >= 0) {
                                 put_binfmt(fmt);
@@ -764,16 +760,16 @@
                                 current->did_exec = 1;
                                 return retval;
                         }
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
                         put_binfmt(fmt);
                         if (retval != -ENOEXEC)
                                 break;
                         if (!bprm->file) {
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
                                 return retval;
                         }
                 }
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
                 if (retval != -ENOEXEC) {
                         break;
 #ifdef CONFIG_KMOD
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:10 EST