Skip to content

Commit a74e910

Browse files
edumazetdavem330
authored andcommitted
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 <[email protected]> Cc: Mike Waychison <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b139ba4 commit a74e910

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

net/socket.c

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,7 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
19081908
__attribute__ ((aligned(sizeof(__kernel_size_t))));
19091909
/* 20 is size of ipv6_pktinfo */
19101910
unsigned char *ctl_buf = ctl;
1911-
int err, ctl_len, iov_size, total_len;
1911+
int err, ctl_len, total_len;
19121912

19131913
err = -EFAULT;
19141914
if (MSG_CMSG_COMPAT & flags) {
@@ -1917,16 +1917,13 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
19171917
} else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
19181918
return -EFAULT;
19191919

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);
19281920
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);
19301927
if (!iov)
19311928
goto out;
19321929
}
@@ -2005,7 +2002,7 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
20052002
sock_kfree_s(sock->sk, ctl_buf, ctl_len);
20062003
out_freeiov:
20072004
if (iov != iovstack)
2008-
sock_kfree_s(sock->sk, iov, iov_size);
2005+
kfree(iov);
20092006
out:
20102007
return err;
20112008
}
@@ -2103,7 +2100,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
21032100
struct iovec iovstack[UIO_FASTIOV];
21042101
struct iovec *iov = iovstack;
21052102
unsigned long cmsg_ptr;
2106-
int err, iov_size, total_len, len;
2103+
int err, total_len, len;
21072104

21082105
/* kernel mode address */
21092106
struct sockaddr_storage addr;
@@ -2118,15 +2115,13 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
21182115
} else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
21192116
return -EFAULT;
21202117

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);
21282118
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);
21302125
if (!iov)
21312126
goto out;
21322127
}
@@ -2180,7 +2175,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
21802175

21812176
out_freeiov:
21822177
if (iov != iovstack)
2183-
sock_kfree_s(sock->sk, iov, iov_size);
2178+
kfree(iov);
21842179
out:
21852180
return err;
21862181
}

0 commit comments

Comments
 (0)