tcp: remove sk_{tr}x_skb_cache
This reverts the following patches : - commit2e05fcae83
("tcp: fix compile error if !CONFIG_SYSCTL") - commit4f661542a4
("tcp: fix zerocopy and notsent_lowat issues") - commit472c2e07ee
("tcp: add one skb cache for tx") - commit8b27dae5a2
("tcp: add one skb cache for rx") Having a cache of one skb (in each direction) per TCP socket is fragile, since it can cause a significant increase of memory needs, and not good enough for high speed flows anyway where more than one skb is needed. We want instead to add a generic infrastructure, with more flexible per-cpu caches, for alien NUMA nodes. Acked-by: Paolo Abeni <pabeni@redhat.com> Acked-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ff6fb083a0
commit
d8b81175e4
@ -989,14 +989,6 @@ tcp_challenge_ack_limit - INTEGER
|
|||||||
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
||||||
Default: 1000
|
Default: 1000
|
||||||
|
|
||||||
tcp_rx_skb_cache - BOOLEAN
|
|
||||||
Controls a per TCP socket cache of one skb, that might help
|
|
||||||
performance of some workloads. This might be dangerous
|
|
||||||
on systems with a lot of TCP sockets, since it increases
|
|
||||||
memory usage.
|
|
||||||
|
|
||||||
Default: 0 (disabled)
|
|
||||||
|
|
||||||
UDP variables
|
UDP variables
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -262,7 +262,6 @@ struct bpf_local_storage;
|
|||||||
* @sk_dst_cache: destination cache
|
* @sk_dst_cache: destination cache
|
||||||
* @sk_dst_pending_confirm: need to confirm neighbour
|
* @sk_dst_pending_confirm: need to confirm neighbour
|
||||||
* @sk_policy: flow policy
|
* @sk_policy: flow policy
|
||||||
* @sk_rx_skb_cache: cache copy of recently accessed RX skb
|
|
||||||
* @sk_receive_queue: incoming packets
|
* @sk_receive_queue: incoming packets
|
||||||
* @sk_wmem_alloc: transmit queue bytes committed
|
* @sk_wmem_alloc: transmit queue bytes committed
|
||||||
* @sk_tsq_flags: TCP Small Queues flags
|
* @sk_tsq_flags: TCP Small Queues flags
|
||||||
@ -328,7 +327,6 @@ struct bpf_local_storage;
|
|||||||
* @sk_peek_off: current peek_offset value
|
* @sk_peek_off: current peek_offset value
|
||||||
* @sk_send_head: front of stuff to transmit
|
* @sk_send_head: front of stuff to transmit
|
||||||
* @tcp_rtx_queue: TCP re-transmit queue [union with @sk_send_head]
|
* @tcp_rtx_queue: TCP re-transmit queue [union with @sk_send_head]
|
||||||
* @sk_tx_skb_cache: cache copy of recently accessed TX skb
|
|
||||||
* @sk_security: used by security modules
|
* @sk_security: used by security modules
|
||||||
* @sk_mark: generic packet mark
|
* @sk_mark: generic packet mark
|
||||||
* @sk_cgrp_data: cgroup data for this cgroup
|
* @sk_cgrp_data: cgroup data for this cgroup
|
||||||
@ -393,7 +391,6 @@ struct sock {
|
|||||||
atomic_t sk_drops;
|
atomic_t sk_drops;
|
||||||
int sk_rcvlowat;
|
int sk_rcvlowat;
|
||||||
struct sk_buff_head sk_error_queue;
|
struct sk_buff_head sk_error_queue;
|
||||||
struct sk_buff *sk_rx_skb_cache;
|
|
||||||
struct sk_buff_head sk_receive_queue;
|
struct sk_buff_head sk_receive_queue;
|
||||||
/*
|
/*
|
||||||
* The backlog queue is special, it is always used with
|
* The backlog queue is special, it is always used with
|
||||||
@ -442,7 +439,6 @@ struct sock {
|
|||||||
struct sk_buff *sk_send_head;
|
struct sk_buff *sk_send_head;
|
||||||
struct rb_root tcp_rtx_queue;
|
struct rb_root tcp_rtx_queue;
|
||||||
};
|
};
|
||||||
struct sk_buff *sk_tx_skb_cache;
|
|
||||||
struct sk_buff_head sk_write_queue;
|
struct sk_buff_head sk_write_queue;
|
||||||
__s32 sk_peek_off;
|
__s32 sk_peek_off;
|
||||||
int sk_write_pending;
|
int sk_write_pending;
|
||||||
@ -1555,18 +1551,10 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)
|
|||||||
__sk_mem_reclaim(sk, 1 << 20);
|
__sk_mem_reclaim(sk, 1 << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_STATIC_KEY_FALSE(tcp_tx_skb_cache_key);
|
|
||||||
static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
|
static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
sk_wmem_queued_add(sk, -skb->truesize);
|
sk_wmem_queued_add(sk, -skb->truesize);
|
||||||
sk_mem_uncharge(sk, skb->truesize);
|
sk_mem_uncharge(sk, skb->truesize);
|
||||||
if (static_branch_unlikely(&tcp_tx_skb_cache_key) &&
|
|
||||||
!sk->sk_tx_skb_cache && !skb_cloned(skb)) {
|
|
||||||
skb_ext_reset(skb);
|
|
||||||
skb_zcopy_clear(skb, true);
|
|
||||||
sk->sk_tx_skb_cache = skb;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__kfree_skb(skb);
|
__kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2575,7 +2563,6 @@ static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags)
|
|||||||
&skb_shinfo(skb)->tskey);
|
&skb_shinfo(skb)->tskey);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_STATIC_KEY_FALSE(tcp_rx_skb_cache_key);
|
|
||||||
/**
|
/**
|
||||||
* sk_eat_skb - Release a skb if it is no longer needed
|
* sk_eat_skb - Release a skb if it is no longer needed
|
||||||
* @sk: socket to eat this skb from
|
* @sk: socket to eat this skb from
|
||||||
@ -2587,12 +2574,6 @@ DECLARE_STATIC_KEY_FALSE(tcp_rx_skb_cache_key);
|
|||||||
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
|
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
__skb_unlink(skb, &sk->sk_receive_queue);
|
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||||
if (static_branch_unlikely(&tcp_rx_skb_cache_key) &&
|
|
||||||
!sk->sk_rx_skb_cache) {
|
|
||||||
sk->sk_rx_skb_cache = skb;
|
|
||||||
skb_orphan(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__kfree_skb(skb);
|
__kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,10 +133,6 @@ void inet_sock_destruct(struct sock *sk)
|
|||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
|
||||||
__skb_queue_purge(&sk->sk_receive_queue);
|
__skb_queue_purge(&sk->sk_receive_queue);
|
||||||
if (sk->sk_rx_skb_cache) {
|
|
||||||
__kfree_skb(sk->sk_rx_skb_cache);
|
|
||||||
sk->sk_rx_skb_cache = NULL;
|
|
||||||
}
|
|
||||||
__skb_queue_purge(&sk->sk_error_queue);
|
__skb_queue_purge(&sk->sk_error_queue);
|
||||||
|
|
||||||
sk_mem_reclaim(sk);
|
sk_mem_reclaim(sk);
|
||||||
|
@ -585,18 +585,6 @@ static struct ctl_table ipv4_table[] = {
|
|||||||
.extra1 = &sysctl_fib_sync_mem_min,
|
.extra1 = &sysctl_fib_sync_mem_min,
|
||||||
.extra2 = &sysctl_fib_sync_mem_max,
|
.extra2 = &sysctl_fib_sync_mem_max,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.procname = "tcp_rx_skb_cache",
|
|
||||||
.data = &tcp_rx_skb_cache_key.key,
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = proc_do_static_key,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "tcp_tx_skb_cache",
|
|
||||||
.data = &tcp_tx_skb_cache_key.key,
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = proc_do_static_key,
|
|
||||||
},
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -325,11 +325,6 @@ struct tcp_splice_state {
|
|||||||
unsigned long tcp_memory_pressure __read_mostly;
|
unsigned long tcp_memory_pressure __read_mostly;
|
||||||
EXPORT_SYMBOL_GPL(tcp_memory_pressure);
|
EXPORT_SYMBOL_GPL(tcp_memory_pressure);
|
||||||
|
|
||||||
DEFINE_STATIC_KEY_FALSE(tcp_rx_skb_cache_key);
|
|
||||||
EXPORT_SYMBOL(tcp_rx_skb_cache_key);
|
|
||||||
|
|
||||||
DEFINE_STATIC_KEY_FALSE(tcp_tx_skb_cache_key);
|
|
||||||
|
|
||||||
void tcp_enter_memory_pressure(struct sock *sk)
|
void tcp_enter_memory_pressure(struct sock *sk)
|
||||||
{
|
{
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
@ -866,18 +861,6 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,
|
|||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (likely(!size)) {
|
|
||||||
skb = sk->sk_tx_skb_cache;
|
|
||||||
if (skb) {
|
|
||||||
skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
|
|
||||||
sk->sk_tx_skb_cache = NULL;
|
|
||||||
pskb_trim(skb, 0);
|
|
||||||
INIT_LIST_HEAD(&skb->tcp_tsorted_anchor);
|
|
||||||
skb_shinfo(skb)->tx_flags = 0;
|
|
||||||
memset(TCP_SKB_CB(skb), 0, sizeof(struct tcp_skb_cb));
|
|
||||||
return skb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* The TCP header must be at least 32-bit aligned. */
|
/* The TCP header must be at least 32-bit aligned. */
|
||||||
size = ALIGN(size, 4);
|
size = ALIGN(size, 4);
|
||||||
|
|
||||||
@ -2920,11 +2903,6 @@ void tcp_write_queue_purge(struct sock *sk)
|
|||||||
sk_wmem_free_skb(sk, skb);
|
sk_wmem_free_skb(sk, skb);
|
||||||
}
|
}
|
||||||
tcp_rtx_queue_purge(sk);
|
tcp_rtx_queue_purge(sk);
|
||||||
skb = sk->sk_tx_skb_cache;
|
|
||||||
if (skb) {
|
|
||||||
__kfree_skb(skb);
|
|
||||||
sk->sk_tx_skb_cache = NULL;
|
|
||||||
}
|
|
||||||
INIT_LIST_HEAD(&tcp_sk(sk)->tsorted_sent_queue);
|
INIT_LIST_HEAD(&tcp_sk(sk)->tsorted_sent_queue);
|
||||||
sk_mem_reclaim(sk);
|
sk_mem_reclaim(sk);
|
||||||
tcp_clear_all_retrans_hints(tcp_sk(sk));
|
tcp_clear_all_retrans_hints(tcp_sk(sk));
|
||||||
@ -2961,10 +2939,6 @@ int tcp_disconnect(struct sock *sk, int flags)
|
|||||||
|
|
||||||
tcp_clear_xmit_timers(sk);
|
tcp_clear_xmit_timers(sk);
|
||||||
__skb_queue_purge(&sk->sk_receive_queue);
|
__skb_queue_purge(&sk->sk_receive_queue);
|
||||||
if (sk->sk_rx_skb_cache) {
|
|
||||||
__kfree_skb(sk->sk_rx_skb_cache);
|
|
||||||
sk->sk_rx_skb_cache = NULL;
|
|
||||||
}
|
|
||||||
WRITE_ONCE(tp->copied_seq, tp->rcv_nxt);
|
WRITE_ONCE(tp->copied_seq, tp->rcv_nxt);
|
||||||
tp->urg_data = 0;
|
tp->urg_data = 0;
|
||||||
tcp_write_queue_purge(sk);
|
tcp_write_queue_purge(sk);
|
||||||
|
@ -1941,7 +1941,6 @@ static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
|
|||||||
int tcp_v4_rcv(struct sk_buff *skb)
|
int tcp_v4_rcv(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct net *net = dev_net(skb->dev);
|
struct net *net = dev_net(skb->dev);
|
||||||
struct sk_buff *skb_to_free;
|
|
||||||
int sdif = inet_sdif(skb);
|
int sdif = inet_sdif(skb);
|
||||||
int dif = inet_iif(skb);
|
int dif = inet_iif(skb);
|
||||||
const struct iphdr *iph;
|
const struct iphdr *iph;
|
||||||
@ -2082,17 +2081,12 @@ int tcp_v4_rcv(struct sk_buff *skb)
|
|||||||
tcp_segs_in(tcp_sk(sk), skb);
|
tcp_segs_in(tcp_sk(sk), skb);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (!sock_owned_by_user(sk)) {
|
if (!sock_owned_by_user(sk)) {
|
||||||
skb_to_free = sk->sk_rx_skb_cache;
|
|
||||||
sk->sk_rx_skb_cache = NULL;
|
|
||||||
ret = tcp_v4_do_rcv(sk, skb);
|
ret = tcp_v4_do_rcv(sk, skb);
|
||||||
} else {
|
} else {
|
||||||
if (tcp_add_backlog(sk, skb))
|
if (tcp_add_backlog(sk, skb))
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
skb_to_free = NULL;
|
|
||||||
}
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
if (skb_to_free)
|
|
||||||
__kfree_skb(skb_to_free);
|
|
||||||
|
|
||||||
put_and_return:
|
put_and_return:
|
||||||
if (refcounted)
|
if (refcounted)
|
||||||
|
@ -1618,7 +1618,6 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
|
|||||||
|
|
||||||
INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
|
INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb_to_free;
|
|
||||||
int sdif = inet6_sdif(skb);
|
int sdif = inet6_sdif(skb);
|
||||||
int dif = inet6_iif(skb);
|
int dif = inet6_iif(skb);
|
||||||
const struct tcphdr *th;
|
const struct tcphdr *th;
|
||||||
@ -1754,17 +1753,12 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
|
|||||||
tcp_segs_in(tcp_sk(sk), skb);
|
tcp_segs_in(tcp_sk(sk), skb);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (!sock_owned_by_user(sk)) {
|
if (!sock_owned_by_user(sk)) {
|
||||||
skb_to_free = sk->sk_rx_skb_cache;
|
|
||||||
sk->sk_rx_skb_cache = NULL;
|
|
||||||
ret = tcp_v6_do_rcv(sk, skb);
|
ret = tcp_v6_do_rcv(sk, skb);
|
||||||
} else {
|
} else {
|
||||||
if (tcp_add_backlog(sk, skb))
|
if (tcp_add_backlog(sk, skb))
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
skb_to_free = NULL;
|
|
||||||
}
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
if (skb_to_free)
|
|
||||||
__kfree_skb(skb_to_free);
|
|
||||||
put_and_return:
|
put_and_return:
|
||||||
if (refcounted)
|
if (refcounted)
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
Loading…
Reference in New Issue
Block a user