aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c4ce243824bb..86de99ad2976 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1479,7 +1479,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1479 MAX_SKB_FRAGS * PAGE_SIZE); 1479 MAX_SKB_FRAGS * PAGE_SIZE);
1480 1480
1481 skb = sock_alloc_send_pskb(sk, len - data_len, data_len, 1481 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
1482 msg->msg_flags & MSG_DONTWAIT, &err); 1482 msg->msg_flags & MSG_DONTWAIT, &err,
1483 PAGE_ALLOC_COSTLY_ORDER);
1483 if (skb == NULL) 1484 if (skb == NULL)
1484 goto out; 1485 goto out;
1485 1486
@@ -1596,6 +1597,10 @@ out:
1596 return err; 1597 return err;
1597} 1598}
1598 1599
1600/* We use paged skbs for stream sockets, and limit occupancy to 32768
1601 * bytes, and a minimun of a full page.
1602 */
1603#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
1599 1604
1600static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, 1605static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1601 struct msghdr *msg, size_t len) 1606 struct msghdr *msg, size_t len)
@@ -1609,6 +1614,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1609 struct scm_cookie tmp_scm; 1614 struct scm_cookie tmp_scm;
1610 bool fds_sent = false; 1615 bool fds_sent = false;
1611 int max_level; 1616 int max_level;
1617 int data_len;
1612 1618
1613 if (NULL == siocb->scm) 1619 if (NULL == siocb->scm)
1614 siocb->scm = &tmp_scm; 1620 siocb->scm = &tmp_scm;
@@ -1635,40 +1641,22 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1635 goto pipe_err; 1641 goto pipe_err;
1636 1642
1637 while (sent < len) { 1643 while (sent < len) {
1638 /* 1644 size = len - sent;
1639 * Optimisation for the fact that under 0.01% of X
1640 * messages typically need breaking up.
1641 */
1642
1643 size = len-sent;
1644 1645
1645 /* Keep two messages in the pipe so it schedules better */ 1646 /* Keep two messages in the pipe so it schedules better */
1646 if (size > ((sk->sk_sndbuf >> 1) - 64)) 1647 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
1647 size = (sk->sk_sndbuf >> 1) - 64;
1648 1648
1649 if (size > SKB_MAX_ALLOC) 1649 /* allow fallback to order-0 allocations */
1650 size = SKB_MAX_ALLOC; 1650 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
1651
1652 /*
1653 * Grab a buffer
1654 */
1655 1651
1656 skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT, 1652 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
1657 &err);
1658 1653
1659 if (skb == NULL) 1654 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
1655 msg->msg_flags & MSG_DONTWAIT, &err,
1656 get_order(UNIX_SKB_FRAGS_SZ));
1657 if (!skb)
1660 goto out_err; 1658 goto out_err;
1661 1659
1662 /*
1663 * If you pass two values to the sock_alloc_send_skb
1664 * it tries to grab the large buffer with GFP_NOFS
1665 * (which can fail easily), and if it fails grab the
1666 * fallback size buffer which is under a page and will
1667 * succeed. [Alan]
1668 */
1669 size = min_t(int, size, skb_tailroom(skb));
1670
1671
1672 /* Only send the fds in the first buffer */ 1660 /* Only send the fds in the first buffer */
1673 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); 1661 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
1674 if (err < 0) { 1662 if (err < 0) {
@@ -1678,7 +1666,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1678 max_level = err + 1; 1666 max_level = err + 1;
1679 fds_sent = true; 1667 fds_sent = true;
1680 1668
1681 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 1669 skb_put(skb, size - data_len);
1670 skb->data_len = data_len;
1671 skb->len = size;
1672 err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov,
1673 sent, size);
1682 if (err) { 1674 if (err) {
1683 kfree_skb(skb); 1675 kfree_skb(skb);
1684 goto out_err; 1676 goto out_err;
@@ -1890,6 +1882,11 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
1890 return timeo; 1882 return timeo;
1891} 1883}
1892 1884
1885static unsigned int unix_skb_len(const struct sk_buff *skb)
1886{
1887 return skb->len - UNIXCB(skb).consumed;
1888}
1889
1893static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, 1890static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1894 struct msghdr *msg, size_t size, 1891 struct msghdr *msg, size_t size,
1895 int flags) 1892 int flags)
@@ -1977,8 +1974,8 @@ again:
1977 } 1974 }
1978 1975
1979 skip = sk_peek_offset(sk, flags); 1976 skip = sk_peek_offset(sk, flags);
1980 while (skip >= skb->len) { 1977 while (skip >= unix_skb_len(skb)) {
1981 skip -= skb->len; 1978 skip -= unix_skb_len(skb);
1982 last = skb; 1979 last = skb;
1983 skb = skb_peek_next(skb, &sk->sk_receive_queue); 1980 skb = skb_peek_next(skb, &sk->sk_receive_queue);
1984 if (!skb) 1981 if (!skb)
@@ -2005,8 +2002,9 @@ again:
2005 sunaddr = NULL; 2002 sunaddr = NULL;
2006 } 2003 }
2007 2004
2008 chunk = min_t(unsigned int, skb->len - skip, size); 2005 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
2009 if (memcpy_toiovec(msg->msg_iov, skb->data + skip, chunk)) { 2006 if (skb_copy_datagram_iovec(skb, UNIXCB(skb).consumed + skip,
2007 msg->msg_iov, chunk)) {
2010 if (copied == 0) 2008 if (copied == 0)
2011 copied = -EFAULT; 2009 copied = -EFAULT;
2012 break; 2010 break;
@@ -2016,14 +2014,14 @@ again:
2016 2014
2017 /* Mark read part of skb as used */ 2015 /* Mark read part of skb as used */
2018 if (!(flags & MSG_PEEK)) { 2016 if (!(flags & MSG_PEEK)) {
2019 skb_pull(skb, chunk); 2017 UNIXCB(skb).consumed += chunk;
2020 2018
2021 sk_peek_offset_bwd(sk, chunk); 2019 sk_peek_offset_bwd(sk, chunk);
2022 2020
2023 if (UNIXCB(skb).fp) 2021 if (UNIXCB(skb).fp)
2024 unix_detach_fds(siocb->scm, skb); 2022 unix_detach_fds(siocb->scm, skb);
2025 2023
2026 if (skb->len) 2024 if (unix_skb_len(skb))
2027 break; 2025 break;
2028 2026
2029 skb_unlink(skb, &sk->sk_receive_queue); 2027 skb_unlink(skb, &sk->sk_receive_queue);
@@ -2107,7 +2105,7 @@ long unix_inq_len(struct sock *sk)
2107 if (sk->sk_type == SOCK_STREAM || 2105 if (sk->sk_type == SOCK_STREAM ||
2108 sk->sk_type == SOCK_SEQPACKET) { 2106 sk->sk_type == SOCK_SEQPACKET) {
2109 skb_queue_walk(&sk->sk_receive_queue, skb) 2107 skb_queue_walk(&sk->sk_receive_queue, skb)
2110 amount += skb->len; 2108 amount += unix_skb_len(skb);
2111 } else { 2109 } else {
2112 skb = skb_peek(&sk->sk_receive_queue); 2110 skb = skb_peek(&sk->sk_receive_queue);
2113 if (skb) 2111 if (skb)