|
@@ -1655,6 +1655,17 @@ void sock_wfree(struct sk_buff *skb)
|
|
|
}
|
|
|
EXPORT_SYMBOL(sock_wfree);
|
|
|
|
|
|
+/* This variant of sock_wfree() is used by TCP,
|
|
|
+ * since it sets SOCK_USE_WRITE_QUEUE.
|
|
|
+ */
|
|
|
+void __sock_wfree(struct sk_buff *skb)
|
|
|
+{
|
|
|
+ struct sock *sk = skb->sk;
|
|
|
+
|
|
|
+ if (atomic_sub_and_test(skb->truesize, &sk->sk_wmem_alloc))
|
|
|
+ __sk_free(sk);
|
|
|
+}
|
|
|
+
|
|
|
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
|
|
|
{
|
|
|
skb_orphan(skb);
|
|
@@ -1677,8 +1688,21 @@ void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
|
|
|
}
|
|
|
EXPORT_SYMBOL(skb_set_owner_w);
|
|
|
|
|
|
+/* This helper is used by netem, as it can hold packets in its
|
|
|
+ * 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.
|
|
|
+ */
|
|
|
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)
|
|
|
+ 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.
|