aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-04-20 14:04:01 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-21 16:24:20 -0400
commita74e910618efb154936958cfeb2aab7c234478c5 (patch)
treeeda84fcc25b12194b82c14786380121dbf86ec00 /net/socket.c
parentb139ba4e90dccbf4cd4efb112af96a5c9e0b098c (diff)
net: change big iov allocations
iov of more than 8 entries are allocated in sendmsg()/recvmsg() through sock_kmalloc() As these allocations are temporary only and small enough, it makes sense to use plain kmalloc() and avoid sk_omem_alloc atomic overhead. Slightly changed fast path to be even faster. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Mike Waychison <mikew@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/net/socket.c b/net/socket.c
index e34510928dcc..d3aaa4f67a3b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1908,7 +1908,7 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
1908 __attribute__ ((aligned(sizeof(__kernel_size_t)))); 1908 __attribute__ ((aligned(sizeof(__kernel_size_t))));
1909 /* 20 is size of ipv6_pktinfo */ 1909 /* 20 is size of ipv6_pktinfo */
1910 unsigned char *ctl_buf = ctl; 1910 unsigned char *ctl_buf = ctl;
1911 int err, ctl_len, iov_size, total_len; 1911 int err, ctl_len, total_len;
1912 1912
1913 err = -EFAULT; 1913 err = -EFAULT;
1914 if (MSG_CMSG_COMPAT & flags) { 1914 if (MSG_CMSG_COMPAT & flags) {
@@ -1917,16 +1917,13 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
1917 } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) 1917 } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
1918 return -EFAULT; 1918 return -EFAULT;
1919 1919
1920 /* do not move before msg_sys is valid */
1921 err = -EMSGSIZE;
1922 if (msg_sys->msg_iovlen > UIO_MAXIOV)
1923 goto out;
1924
1925 /* Check whether to allocate the iovec area */
1926 err = -ENOMEM;
1927 iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
1928 if (msg_sys->msg_iovlen > UIO_FASTIOV) { 1920 if (msg_sys->msg_iovlen > UIO_FASTIOV) {
1929 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); 1921 err = -EMSGSIZE;
1922 if (msg_sys->msg_iovlen > UIO_MAXIOV)
1923 goto out;
1924 err = -ENOMEM;
1925 iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec),
1926 GFP_KERNEL);
1930 if (!iov) 1927 if (!iov)
1931 goto out; 1928 goto out;
1932 } 1929 }
@@ -2005,7 +2002,7 @@ out_freectl:
2005 sock_kfree_s(sock->sk, ctl_buf, ctl_len); 2002 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
2006out_freeiov: 2003out_freeiov:
2007 if (iov != iovstack) 2004 if (iov != iovstack)
2008 sock_kfree_s(sock->sk, iov, iov_size); 2005 kfree(iov);
2009out: 2006out:
2010 return err; 2007 return err;
2011} 2008}
@@ -2103,7 +2100,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
2103 struct iovec iovstack[UIO_FASTIOV]; 2100 struct iovec iovstack[UIO_FASTIOV];
2104 struct iovec *iov = iovstack; 2101 struct iovec *iov = iovstack;
2105 unsigned long cmsg_ptr; 2102 unsigned long cmsg_ptr;
2106 int err, iov_size, total_len, len; 2103 int err, total_len, len;
2107 2104
2108 /* kernel mode address */ 2105 /* kernel mode address */
2109 struct sockaddr_storage addr; 2106 struct sockaddr_storage addr;
@@ -2118,15 +2115,13 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
2118 } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) 2115 } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
2119 return -EFAULT; 2116 return -EFAULT;
2120 2117
2121 err = -EMSGSIZE;
2122 if (msg_sys->msg_iovlen > UIO_MAXIOV)
2123 goto out;
2124
2125 /* Check whether to allocate the iovec area */
2126 err = -ENOMEM;
2127 iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
2128 if (msg_sys->msg_iovlen > UIO_FASTIOV) { 2118 if (msg_sys->msg_iovlen > UIO_FASTIOV) {
2129 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); 2119 err = -EMSGSIZE;
2120 if (msg_sys->msg_iovlen > UIO_MAXIOV)
2121 goto out;
2122 err = -ENOMEM;
2123 iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec),
2124 GFP_KERNEL);
2130 if (!iov) 2125 if (!iov)
2131 goto out; 2126 goto out;
2132 } 2127 }
@@ -2180,7 +2175,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
2180 2175
2181out_freeiov: 2176out_freeiov:
2182 if (iov != iovstack) 2177 if (iov != iovstack)
2183 sock_kfree_s(sock->sk, iov, iov_size); 2178 kfree(iov);
2184out: 2179out:
2185 return err; 2180 return err;
2186} 2181}