]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/core/sock.c
Merge tag 'at91-ab-4.13-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/abellon...
[mirror_ubuntu-bionic-kernel.git] / net / core / sock.c
index b5baeb9cb0fb1bff2fb7c49c0a850bc493f7e58d..727f924b7f91f495d9e7a4e7297c9c937d3258ed 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/sched/mm.h>
 #include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/sockios.h>
 
 #include <trace/events/sock.h>
 
-#ifdef CONFIG_INET
 #include <net/tcp.h>
-#endif
-
 #include <net/busy_poll.h>
 
 static DEFINE_MUTEX(proto_list_mutex);
@@ -372,14 +370,14 @@ EXPORT_SYMBOL_GPL(sk_clear_memalloc);
 int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
        int ret;
-       unsigned long pflags = current->flags;
+       unsigned int noreclaim_flag;
 
        /* these should have been dropped before queueing */
        BUG_ON(!sock_flag(sk, SOCK_MEMALLOC));
 
-       current->flags |= PF_MEMALLOC;
+       noreclaim_flag = memalloc_noreclaim_save();
        ret = sk->sk_backlog_rcv(sk, skb);
-       current_restore_flags(pflags, PF_MEMALLOC);
+       memalloc_noreclaim_restore(noreclaim_flag);
 
        return ret;
 }
@@ -1802,28 +1800,24 @@ EXPORT_SYMBOL(skb_set_owner_w);
  * delay queue. We want to allow the owner socket to send more
  * packets, as if they were already TX completed by a typical driver.
  * But we also want to keep skb->sk set because some packet schedulers
- * rely on it (sch_fq for example). So we set skb->truesize to a small
- * amount (1) and decrease sk_wmem_alloc accordingly.
+ * rely on it (sch_fq for example).
  */
 void skb_orphan_partial(struct sk_buff *skb)
 {
-       /* If this skb is a TCP pure ACK or already went here,
-        * we have nothing to do. 2 is already a very small truesize.
-        */
-       if (skb->truesize <= 2)
+       if (skb_is_tcp_pure_ack(skb))
                return;
 
-       /* TCP stack sets skb->ooo_okay based on sk_wmem_alloc,
-        * so we do not completely orphan skb, but transfert all
-        * accounted bytes but one, to avoid unexpected reorders.
-        */
        if (skb->destructor == sock_wfree
 #ifdef CONFIG_INET
            || skb->destructor == tcp_wfree
 #endif
                ) {
-               atomic_sub(skb->truesize - 1, &skb->sk->sk_wmem_alloc);
-               skb->truesize = 1;
+               struct sock *sk = skb->sk;
+
+               if (atomic_inc_not_zero(&sk->sk_refcnt)) {
+                       atomic_sub(skb->truesize, &sk->sk_wmem_alloc);
+                       skb->destructor = sock_efree;
+               }
        } else {
                skb_orphan(skb);
        }