aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvtap.c2
-rw-r--r--drivers/net/tun.c2
-rw-r--r--include/net/sock.h3
-rw-r--r--net/core/sock.c100
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/unix/af_unix.c6
6 files changed, 60 insertions, 55 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 182364abfa35..8f6056d9ba97 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -524,7 +524,7 @@ static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
524 linear = len; 524 linear = len;
525 525
526 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, 526 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
527 err); 527 err, 0);
528 if (!skb) 528 if (!skb)
529 return NULL; 529 return NULL;
530 530
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index b1630479d4a1..978d8654b14a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -949,7 +949,7 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile,
949 linear = len; 949 linear = len;
950 950
951 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, 951 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
952 &err); 952 &err, 0);
953 if (!skb) 953 if (!skb)
954 return ERR_PTR(err); 954 return ERR_PTR(err);
955 955
diff --git a/include/net/sock.h b/include/net/sock.h
index ab6a8b75207e..e4bbcbfd07ea 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1539,7 +1539,8 @@ extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
1539 unsigned long header_len, 1539 unsigned long header_len,
1540 unsigned long data_len, 1540 unsigned long data_len,
1541 int noblock, 1541 int noblock,
1542 int *errcode); 1542 int *errcode,
1543 int max_page_order);
1543extern void *sock_kmalloc(struct sock *sk, int size, 1544extern void *sock_kmalloc(struct sock *sk, int size,
1544 gfp_t priority); 1545 gfp_t priority);
1545extern void sock_kfree_s(struct sock *sk, void *mem, int size); 1546extern void sock_kfree_s(struct sock *sk, void *mem, int size);
diff --git a/net/core/sock.c b/net/core/sock.c
index 83667de45ec9..5b6beba494a3 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1741,24 +1741,23 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)
1741 1741
1742struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, 1742struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
1743 unsigned long data_len, int noblock, 1743 unsigned long data_len, int noblock,
1744 int *errcode) 1744 int *errcode, int max_page_order)
1745{ 1745{
1746 struct sk_buff *skb; 1746 struct sk_buff *skb = NULL;
1747 unsigned long chunk;
1747 gfp_t gfp_mask; 1748 gfp_t gfp_mask;
1748 long timeo; 1749 long timeo;
1749 int err; 1750 int err;
1750 int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 1751 int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1752 struct page *page;
1753 int i;
1751 1754
1752 err = -EMSGSIZE; 1755 err = -EMSGSIZE;
1753 if (npages > MAX_SKB_FRAGS) 1756 if (npages > MAX_SKB_FRAGS)
1754 goto failure; 1757 goto failure;
1755 1758
1756 gfp_mask = sk->sk_allocation;
1757 if (gfp_mask & __GFP_WAIT)
1758 gfp_mask |= __GFP_REPEAT;
1759
1760 timeo = sock_sndtimeo(sk, noblock); 1759 timeo = sock_sndtimeo(sk, noblock);
1761 while (1) { 1760 while (!skb) {
1762 err = sock_error(sk); 1761 err = sock_error(sk);
1763 if (err != 0) 1762 if (err != 0)
1764 goto failure; 1763 goto failure;
@@ -1767,50 +1766,52 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
1767 if (sk->sk_shutdown & SEND_SHUTDOWN) 1766 if (sk->sk_shutdown & SEND_SHUTDOWN)
1768 goto failure; 1767 goto failure;
1769 1768
1770 if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { 1769 if (atomic_read(&sk->sk_wmem_alloc) >= sk->sk_sndbuf) {
1771 skb = alloc_skb(header_len, gfp_mask); 1770 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
1772 if (skb) { 1771 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1773 int i; 1772 err = -EAGAIN;
1774 1773 if (!timeo)
1775 /* No pages, we're done... */ 1774 goto failure;
1776 if (!data_len) 1775 if (signal_pending(current))
1777 break; 1776 goto interrupted;
1778 1777 timeo = sock_wait_for_wmem(sk, timeo);
1779 skb->truesize += data_len; 1778 continue;
1780 skb_shinfo(skb)->nr_frags = npages; 1779 }
1781 for (i = 0; i < npages; i++) {
1782 struct page *page;
1783
1784 page = alloc_pages(sk->sk_allocation, 0);
1785 if (!page) {
1786 err = -ENOBUFS;
1787 skb_shinfo(skb)->nr_frags = i;
1788 kfree_skb(skb);
1789 goto failure;
1790 }
1791
1792 __skb_fill_page_desc(skb, i,
1793 page, 0,
1794 (data_len >= PAGE_SIZE ?
1795 PAGE_SIZE :
1796 data_len));
1797 data_len -= PAGE_SIZE;
1798 }
1799 1780
1800 /* Full success... */ 1781 err = -ENOBUFS;
1801 break; 1782 gfp_mask = sk->sk_allocation;
1802 } 1783 if (gfp_mask & __GFP_WAIT)
1803 err = -ENOBUFS; 1784 gfp_mask |= __GFP_REPEAT;
1785
1786 skb = alloc_skb(header_len, gfp_mask);
1787 if (!skb)
1804 goto failure; 1788 goto failure;
1789
1790 skb->truesize += data_len;
1791
1792 for (i = 0; npages > 0; i++) {
1793 int order = max_page_order;
1794
1795 while (order) {
1796 if (npages >= 1 << order) {
1797 page = alloc_pages(sk->sk_allocation |
1798 __GFP_COMP | __GFP_NOWARN,
1799 order);
1800 if (page)
1801 goto fill_page;
1802 }
1803 order--;
1804 }
1805 page = alloc_page(sk->sk_allocation);
1806 if (!page)
1807 goto failure;
1808fill_page:
1809 chunk = min_t(unsigned long, data_len,
1810 PAGE_SIZE << order);
1811 skb_fill_page_desc(skb, i, page, 0, chunk);
1812 data_len -= chunk;
1813 npages -= 1 << order;
1805 } 1814 }
1806 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
1807 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1808 err = -EAGAIN;
1809 if (!timeo)
1810 goto failure;
1811 if (signal_pending(current))
1812 goto interrupted;
1813 timeo = sock_wait_for_wmem(sk, timeo);
1814 } 1815 }
1815 1816
1816 skb_set_owner_w(skb, sk); 1817 skb_set_owner_w(skb, sk);
@@ -1819,6 +1820,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
1819interrupted: 1820interrupted:
1820 err = sock_intr_errno(timeo); 1821 err = sock_intr_errno(timeo);
1821failure: 1822failure:
1823 kfree_skb(skb);
1822 *errcode = err; 1824 *errcode = err;
1823 return NULL; 1825 return NULL;
1824} 1826}
@@ -1827,7 +1829,7 @@ EXPORT_SYMBOL(sock_alloc_send_pskb);
1827struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, 1829struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
1828 int noblock, int *errcode) 1830 int noblock, int *errcode)
1829{ 1831{
1830 return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); 1832 return sock_alloc_send_pskb(sk, size, 0, noblock, errcode, 0);
1831} 1833}
1832EXPORT_SYMBOL(sock_alloc_send_skb); 1834EXPORT_SYMBOL(sock_alloc_send_skb);
1833 1835
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 4cb28a7f639b..6c53dd9f5ccc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2181,7 +2181,7 @@ static struct sk_buff *packet_alloc_skb(struct sock *sk, size_t prepad,
2181 linear = len; 2181 linear = len;
2182 2182
2183 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, 2183 skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
2184 err); 2184 err, 0);
2185 if (!skb) 2185 if (!skb)
2186 return NULL; 2186 return NULL;
2187 2187
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 99dc760cdd95..fee9e3397cd1 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
@@ -1651,7 +1652,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1651 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0)); 1652 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
1652 1653
1653 skb = sock_alloc_send_pskb(sk, size - data_len, data_len, 1654 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
1654 msg->msg_flags & MSG_DONTWAIT, &err); 1655 msg->msg_flags & MSG_DONTWAIT, &err,
1656 get_order(UNIX_SKB_FRAGS_SZ));
1655 if (!skb) 1657 if (!skb)
1656 goto out_err; 1658 goto out_err;
1657 1659