void sock_wfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
-       int res;
+       unsigned int len = skb->truesize;
 
-       /* In case it might be waiting for more memory. */
-       res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
-       if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
+       if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
+               /*
+                * Keep a reference on sk_wmem_alloc, this will be released
+                * after sk_write_space() call
+                */
+               atomic_sub(len - 1, &sk->sk_wmem_alloc);
                sk->sk_write_space(sk);
+               len = 1;
+       }
        /*
-        * if sk_wmem_alloc reached 0, we are last user and should
-        * free this sock, as sk_free() call could not do it.
+        * if sk_wmem_alloc reaches 0, we must finish what sk_free()
+        * could not do because of in-flight packets
         */
-       if (res == 0)
+       if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
                __sk_free(sk);
 }
 EXPORT_SYMBOL(sock_wfree);