提交 3df684c1 编写于 作者: E Eric Dumazet 提交者: David S. Miller

tcp: avoid indirect calls to sock_rfree

TCP uses sk_eat_skb() when skbs can be removed from receive queue.
However, the call to skb_orphan() from __kfree_skb() incurs
an indirect call so sock_rfee(), which is more expensive than
a direct call, especially for CONFIG_RETPOLINE=y.

Add tcp_eat_recv_skb() function to make the call before
__kfree_skb().
Signed-off-by: NEric Dumazet <edumazet@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 b96c51bd
...@@ -1580,6 +1580,16 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) ...@@ -1580,6 +1580,16 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
tcp_send_ack(sk); tcp_send_ack(sk);
} }
static void tcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
{
if (likely(skb->destructor == sock_rfree)) {
sock_rfree(skb);
skb->destructor = NULL;
skb->sk = NULL;
}
sk_eat_skb(sk, skb);
}
static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1599,7 +1609,7 @@ static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) ...@@ -1599,7 +1609,7 @@ static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
* splitted a fat GRO packet, while we released socket lock * splitted a fat GRO packet, while we released socket lock
* in skb_splice_bits() * in skb_splice_bits()
*/ */
sk_eat_skb(sk, skb); tcp_eat_recv_skb(sk, skb);
} }
return NULL; return NULL;
} }
...@@ -1665,11 +1675,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, ...@@ -1665,11 +1675,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
continue; continue;
} }
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) { if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) {
sk_eat_skb(sk, skb); tcp_eat_recv_skb(sk, skb);
++seq; ++seq;
break; break;
} }
sk_eat_skb(sk, skb); tcp_eat_recv_skb(sk, skb);
if (!desc->count) if (!desc->count)
break; break;
WRITE_ONCE(tp->copied_seq, seq); WRITE_ONCE(tp->copied_seq, seq);
...@@ -2481,14 +2491,14 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len, ...@@ -2481,14 +2491,14 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
goto found_fin_ok; goto found_fin_ok;
if (!(flags & MSG_PEEK)) if (!(flags & MSG_PEEK))
sk_eat_skb(sk, skb); tcp_eat_recv_skb(sk, skb);
continue; continue;
found_fin_ok: found_fin_ok:
/* Process the FIN. */ /* Process the FIN. */
WRITE_ONCE(*seq, *seq + 1); WRITE_ONCE(*seq, *seq + 1);
if (!(flags & MSG_PEEK)) if (!(flags & MSG_PEEK))
sk_eat_skb(sk, skb); tcp_eat_recv_skb(sk, skb);
break; break;
} while (len > 0); } while (len > 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册