Hello folks,

Here's an updated copy of the patch to use fget_light in net/socket.c.  
Rerunning the tests show a drop of ~80Mbit/s on average, which looks 
bad until you see the drop in cpu usage from ~89% to ~82%.  That will 
get fixed in another patch...

Before: max 8113.70, min 8026.32, avg 8072.34
 87380  16384  16384    10.01      8045.55   87.11    87.11    1.774   1.774 
 87380  16384  16384    10.01      8065.14   90.86    90.86    1.846   1.846 
 87380  16384  16384    10.00      8077.76   89.85    89.85    1.822   1.822 
 87380  16384  16384    10.00      8026.32   89.80    89.80    1.833   1.833 
 87380  16384  16384    10.01      8108.59   89.81    89.81    1.815   1.815 
 87380  16384  16384    10.01      8034.53   89.01    89.01    1.815   1.815 
 87380  16384  16384    10.00      8113.70   90.45    90.45    1.827   1.827 
 87380  16384  16384    10.00      8111.37   89.90    89.90    1.816   1.816 
 87380  16384  16384    10.01      8077.75   87.96    87.96    1.784   1.784 
 87380  16384  16384    10.00      8062.70   90.25    90.25    1.834   1.834 

After: max 8035.81, min 7963.69, avg 7998.14
 87380  16384  16384    10.01      8000.93   82.11    82.11    1.682   1.682 
 87380  16384  16384    10.01      8016.17   83.67    83.67    1.710   1.710 
 87380  16384  16384    10.01      7963.69   83.47    83.47    1.717   1.717 
 87380  16384  16384    10.01      8014.35   81.71    81.71    1.671   1.671 
 87380  16384  16384    10.00      7967.68   83.41    83.41    1.715   1.715 
 87380  16384  16384    10.00      7995.22   81.00    81.00    1.660   1.660 
 87380  16384  16384    10.00      8002.61   83.90    83.90    1.718   1.718 
 87380  16384  16384    10.00      8035.81   81.71    81.71    1.666   1.666 
 87380  16384  16384    10.01      8005.36   82.56    82.56    1.690   1.690 
 87380  16384  16384    10.00      7979.61   82.50    82.50    1.694   1.694 


-- 
"Time is of no importance, Mr. President, only life is important."
Don't Email: <[EMAIL PROTECTED]>.

Signed-off-by: Benjamin LaHaise <[EMAIL PROTECTED]>
diff --git a/net/socket.c b/net/socket.c
index 3ca31e8..24c4a1a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -429,6 +429,28 @@ int sock_map_fd(struct socket *sock)
        return fd;
 }
 
+static struct socket *sock_from_file(struct file *file, int *err)
+{
+       struct inode *inode;
+       struct socket *sock;
+
+       if (file->f_op == &socket_file_ops)
+               return file->private_data;      /* set in sock_map_fd */
+
+       inode = file->f_dentry->d_inode;
+       if (!S_ISSOCK(inode->i_mode)) {
+               *err = -ENOTSOCK;
+               return NULL;
+       }
+
+       sock = SOCKET_I(inode);
+       if (sock->file != file) {
+               printk(KERN_ERR "socki_lookup: socket file changed!\n");
+               sock->file = file;
+       }
+       return sock;
+}
+
 /**
  *     sockfd_lookup   -       Go from a file number to its socket slot
  *     @fd: file handle
@@ -445,31 +467,31 @@ int sock_map_fd(struct socket *sock)
 struct socket *sockfd_lookup(int fd, int *err)
 {
        struct file *file;
-       struct inode *inode;
        struct socket *sock;
 
-       if (!(file = fget(fd)))
-       {
+       if (!(file = fget(fd))) {
                *err = -EBADF;
                return NULL;
        }
-
-       if (file->f_op == &socket_file_ops)
-               return file->private_data;      /* set in sock_map_fd */
-
-       inode = file->f_dentry->d_inode;
-       if (!S_ISSOCK(inode->i_mode)) {
-               *err = -ENOTSOCK;
+       sock = sock_from_file(file, err);
+       if (!sock)
                fput(file);
-               return NULL;
-       }
+       return sock;
+}
 
-       sock = SOCKET_I(inode);
-       if (sock->file != file) {
-               printk(KERN_ERR "socki_lookup: socket file changed!\n");
-               sock->file = file;
+static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
+{
+       struct file *file;
+       struct socket *sock;
+
+       file = fget_light(fd, fput_needed);
+       if (file) {
+               sock = sock_from_file(file, err);
+               if (sock)
+                       return sock;
+               fput_light(file, *fput_needed);
        }
-       return sock;
+       return NULL;
 }
 
 /**
@@ -1304,19 +1326,17 @@ asmlinkage long sys_bind(int fd, struct 
 {
        struct socket *sock;
        char address[MAX_SOCK_ADDR];
-       int err;
+       int err, fput_needed;
 
-       if((sock = sockfd_lookup(fd,&err))!=NULL)
+       if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
        {
                if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
                        err = security_socket_bind(sock, (struct sockaddr 
*)address, addrlen);
-                       if (err) {
-                               sockfd_put(sock);
-                               return err;
-                       }
-                       err = sock->ops->bind(sock, (struct sockaddr *)address, 
addrlen);
+                       if (!err)
+                               err = sock->ops->bind(sock,
+                                       (struct sockaddr *)address, addrlen);
                }
-               sockfd_put(sock);
+               fput_light(sock->file, fput_needed);
        }                       
        return err;
 }
@@ -1333,20 +1353,17 @@ int sysctl_somaxconn = SOMAXCONN;
 asmlinkage long sys_listen(int fd, int backlog)
 {
        struct socket *sock;
-       int err;
+       int err, fput_needed;
        
-       if ((sock = sockfd_lookup(fd, &err)) != NULL) {
+       if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
                if ((unsigned) backlog > sysctl_somaxconn)
                        backlog = sysctl_somaxconn;
 
                err = security_socket_listen(sock, backlog);
-               if (err) {
-                       sockfd_put(sock);
-                       return err;
-               }
+               if (!err)
+                       err = sock->ops->listen(sock, backlog);
 
-               err=sock->ops->listen(sock, backlog);
-               sockfd_put(sock);
+               fput_light(sock->file, fput_needed);
        }
        return err;
 }
@@ -1368,10 +1385,10 @@ asmlinkage long sys_accept(int fd, struc
 {
        struct socket *sock, *newsock;
        struct file *newfile;
-       int err, len, newfd;
+       int err, len, newfd, fput_needed;
        char address[MAX_SOCK_ADDR];
 
-       sock = sockfd_lookup(fd, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
@@ -1424,7 +1441,7 @@ asmlinkage long sys_accept(int fd, struc
        security_socket_post_accept(sock, newsock);
 
 out_put:
-       sockfd_put(sock);
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 out_fd:
@@ -1452,9 +1469,9 @@ asmlinkage long sys_connect(int fd, stru
 {
        struct socket *sock;
        char address[MAX_SOCK_ADDR];
-       int err;
+       int err, fput_needed;
 
-       sock = sockfd_lookup(fd, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
        err = move_addr_to_kernel(uservaddr, addrlen, address);
@@ -1468,7 +1485,7 @@ asmlinkage long sys_connect(int fd, stru
        err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
                                 sock->file->f_flags);
 out_put:
-       sockfd_put(sock);
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 }
@@ -1482,9 +1499,9 @@ asmlinkage long sys_getsockname(int fd, 
 {
        struct socket *sock;
        char address[MAX_SOCK_ADDR];
-       int len, err;
+       int len, err, fput_needed;
        
-       sock = sockfd_lookup(fd, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
@@ -1498,7 +1515,7 @@ asmlinkage long sys_getsockname(int fd, 
        err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
 
 out_put:
-       sockfd_put(sock);
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 }
@@ -1512,20 +1529,19 @@ asmlinkage long sys_getpeername(int fd, 
 {
        struct socket *sock;
        char address[MAX_SOCK_ADDR];
-       int len, err;
+       int len, err, fput_needed;
 
-       if ((sock = sockfd_lookup(fd, &err))!=NULL)
-       {
+       if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
                err = security_socket_getpeername(sock);
                if (err) {
-                       sockfd_put(sock);
+                       fput_light(sock->file, fput_needed);
                        return err;
                }
 
                err = sock->ops->getname(sock, (struct sockaddr *)address, 
&len, 1);
                if (!err)
                        err=move_addr_to_user(address,len, usockaddr, 
usockaddr_len);
-               sockfd_put(sock);
+               fput_light(sock->file, fput_needed);
        }
        return err;
 }
@@ -1544,10 +1560,16 @@ asmlinkage long sys_sendto(int fd, void 
        int err;
        struct msghdr msg;
        struct iovec iov;
-       
-       sock = sockfd_lookup(fd, &err);
+       int fput_needed;
+       struct file *sock_file;
+
+       sock_file = fget_light(fd, &fput_needed);
+       if (!sock_file)
+               return -EBADF;
+
+       sock = sock_from_file(sock_file, &err);
        if (!sock)
-               goto out;
+               goto out_put;
        iov.iov_base=buff;
        iov.iov_len=len;
        msg.msg_name=NULL;
@@ -1556,8 +1578,7 @@ asmlinkage long sys_sendto(int fd, void 
        msg.msg_control=NULL;
        msg.msg_controllen=0;
        msg.msg_namelen=0;
-       if(addr)
-       {
+       if (addr) {
                err = move_addr_to_kernel(addr, addr_len, address);
                if (err < 0)
                        goto out_put;
@@ -1570,8 +1591,7 @@ asmlinkage long sys_sendto(int fd, void 
        err = sock_sendmsg(sock, &msg, len);
 
 out_put:               
-       sockfd_put(sock);
-out:
+       fput_light(sock_file, fput_needed);
        return err;
 }
 
@@ -1598,8 +1618,14 @@ asmlinkage long sys_recvfrom(int fd, voi
        struct msghdr msg;
        char address[MAX_SOCK_ADDR];
        int err,err2;
+       struct file *sock_file;
+       int fput_needed;
+
+       sock_file = fget_light(fd, &fput_needed);
+       if (!sock_file)
+               return -EBADF;
 
-       sock = sockfd_lookup(fd, &err);
+       sock = sock_from_file(sock_file, &err);
        if (!sock)
                goto out;
 
@@ -1621,8 +1647,8 @@ asmlinkage long sys_recvfrom(int fd, voi
                if(err2<0)
                        err=err2;
        }
-       sockfd_put(sock);                       
 out:
+       fput_light(sock_file, fput_needed);                     
        return err;
 }
 
@@ -1642,25 +1668,24 @@ asmlinkage long sys_recv(int fd, void __
 
 asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user 
*optval, int optlen)
 {
-       int err;
+       int err, fput_needed;
        struct socket *sock;
 
        if (optlen < 0)
                return -EINVAL;
                        
-       if ((sock = sockfd_lookup(fd, &err))!=NULL)
+       if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL)
        {
                err = security_socket_setsockopt(sock,level,optname);
-               if (err) {
-                       sockfd_put(sock);
-                       return err;
-               }
+               if (err)
+                       goto out_put;
 
                if (level == SOL_SOCKET)
                        err=sock_setsockopt(sock,level,optname,optval,optlen);
                else
                        err=sock->ops->setsockopt(sock, level, optname, optval, 
optlen);
-               sockfd_put(sock);
+out_put:
+               fput_light(sock->file, fput_needed);
        }
        return err;
 }
@@ -1672,23 +1697,20 @@ asmlinkage long sys_setsockopt(int fd, i
 
 asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user 
*optval, int __user *optlen)
 {
-       int err;
+       int err, fput_needed;
        struct socket *sock;
 
-       if ((sock = sockfd_lookup(fd, &err))!=NULL)
-       {
-               err = security_socket_getsockopt(sock, level, 
-                                                          optname);
-               if (err) {
-                       sockfd_put(sock);
-                       return err;
-               }
+       if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
+               err = security_socket_getsockopt(sock, level, optname);
+               if (err)
+                       goto out_put;
 
                if (level == SOL_SOCKET)
                        err=sock_getsockopt(sock,level,optname,optval,optlen);
                else
                        err=sock->ops->getsockopt(sock, level, optname, optval, 
optlen);
-               sockfd_put(sock);
+out_put:
+               fput_light(sock->file, fput_needed);
        }
        return err;
 }
@@ -1700,19 +1722,15 @@ asmlinkage long sys_getsockopt(int fd, i
 
 asmlinkage long sys_shutdown(int fd, int how)
 {
-       int err;
+       int err, fput_needed;
        struct socket *sock;
 
-       if ((sock = sockfd_lookup(fd, &err))!=NULL)
+       if ((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
        {
                err = security_socket_shutdown(sock, how);
-               if (err) {
-                       sockfd_put(sock);
-                       return err;
-               }
-                               
-               err=sock->ops->shutdown(sock, how);
-               sockfd_put(sock);
+               if (!err)
+                       err = sock->ops->shutdown(sock, how);
+               fput_light(sock->file, fput_needed);
        }
        return err;
 }
@@ -1741,6 +1759,7 @@ asmlinkage long sys_sendmsg(int fd, stru
        unsigned char *ctl_buf = ctl;
        struct msghdr msg_sys;
        int err, ctl_len, iov_size, total_len;
+       int fput_needed;
        
        err = -EFAULT;
        if (MSG_CMSG_COMPAT & flags) {
@@ -1749,7 +1768,7 @@ asmlinkage long sys_sendmsg(int fd, stru
        } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
                return -EFAULT;
 
-       sock = sockfd_lookup(fd, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock) 
                goto out;
 
@@ -1817,7 +1836,7 @@ out_freeiov:
        if (iov != iovstack)
                sock_kfree_s(sock->sk, iov, iov_size);
 out_put:
-       sockfd_put(sock);
+       fput_light(sock->file, fput_needed);
 out:       
        return err;
 }
@@ -1835,6 +1854,7 @@ asmlinkage long sys_recvmsg(int fd, stru
        struct msghdr msg_sys;
        unsigned long cmsg_ptr;
        int err, iov_size, total_len, len;
+       int fput_needed;
 
        /* kernel mode address */
        char addr[MAX_SOCK_ADDR];
@@ -1850,7 +1870,7 @@ asmlinkage long sys_recvmsg(int fd, stru
                if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr)))
                        return -EFAULT;
 
-       sock = sockfd_lookup(fd, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
@@ -1917,7 +1937,7 @@ out_freeiov:
        if (iov != iovstack)
                sock_kfree_s(sock->sk, iov, iov_size);
 out_put:
-       sockfd_put(sock);
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 }

----- End forwarded message -----
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to