mm, page_alloc: distinguish between being unable to sleep, unwilling to sleep and...
[firefly-linux-kernel-4.4.55.git] / net / core / sock.c
index 0ef30aa90132c7a1a04971c773d4de8ed4ac146b..1e4dd54bfb5a525ef6070905f07472f60e9f137f 100644 (file)
@@ -1656,6 +1656,28 @@ void sock_wfree(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(sock_wfree);
 
+void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
+{
+       skb_orphan(skb);
+       skb->sk = sk;
+#ifdef CONFIG_INET
+       if (unlikely(!sk_fullsock(sk))) {
+               skb->destructor = sock_edemux;
+               sock_hold(sk);
+               return;
+       }
+#endif
+       skb->destructor = sock_wfree;
+       skb_set_hash_from_sk(skb, sk);
+       /*
+        * We used to take a refcount on sk, but following operation
+        * is enough to guarantee sk_free() wont free this sock until
+        * all in-flight packets are completed
+        */
+       atomic_add(skb->truesize, &sk->sk_wmem_alloc);
+}
+EXPORT_SYMBOL(skb_set_owner_w);
+
 void skb_orphan_partial(struct sk_buff *skb)
 {
        /* TCP stack sets skb->ooo_okay based on sk_wmem_alloc,
@@ -1922,8 +1944,10 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
 
        pfrag->offset = 0;
        if (SKB_FRAG_PAGE_ORDER) {
-               pfrag->page = alloc_pages((gfp & ~__GFP_WAIT) | __GFP_COMP |
-                                         __GFP_NOWARN | __GFP_NORETRY,
+               /* Avoid direct reclaim but allow kswapd to wake */
+               pfrag->page = alloc_pages((gfp & ~__GFP_DIRECT_RECLAIM) |
+                                         __GFP_COMP | __GFP_NOWARN |
+                                         __GFP_NORETRY,
                                          SKB_FRAG_PAGE_ORDER);
                if (likely(pfrag->page)) {
                        pfrag->size = PAGE_SIZE << SKB_FRAG_PAGE_ORDER;