Commit 858f5017 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

tcp: do not recycle cloned skbs



It is illegal to change arbitrary fields in skb_shared_info if the
skb is cloned.

Before calling skb_zcopy_clear() we need to ensure this rule,
therefore we need to move the test from sk_stream_alloc_skb()
to sk_wmem_free_skb()

Fixes: 4f661542 ("tcp: fix zerocopy and notsent_lowat issues")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Diagnosed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 22fb43f3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1473,7 +1473,7 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
	sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
	sk->sk_wmem_queued -= skb->truesize;
	sk_mem_uncharge(sk, skb->truesize);
	if (!sk->sk_tx_skb_cache) {
	if (!sk->sk_tx_skb_cache && !skb_cloned(skb)) {
		skb_zcopy_clear(skb, true);
		sk->sk_tx_skb_cache = skb;
		return;
+1 −1
Original line number Diff line number Diff line
@@ -855,7 +855,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,

	if (likely(!size)) {
		skb = sk->sk_tx_skb_cache;
		if (skb && !skb_cloned(skb)) {
		if (skb) {
			skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
			sk->sk_tx_skb_cache = NULL;
			pskb_trim(skb, 0);