mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
tcp: Save lock_sock() for memcg in inet_csk_accept().
If memcg is enabled, accept() acquires lock_sock() twice for each new TCP/MPTCP socket in inet_csk_accept() and __inet_accept(). Let's move memcg operations from inet_csk_accept() to __inet_accept(). Note that SCTP somehow allocates a new socket by sk_alloc() in sk->sk_prot->accept() and clones fields manually, instead of using sk_clone_lock(). mem_cgroup_sk_alloc() is called for SCTP before __inet_accept(), so I added the protocol check in __inet_accept(), but this can be removed once SCTP uses sk_clone_lock(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: Roman Gushchin <roman.gushchin@linux.dev> Link: https://patch.msgid.link/20251014235604.3057003-2-kuniyu@google.com
This commit is contained in:
committed by
Martin KaFai Lau
parent
55db64ddd6
commit
4a997d49d9
@@ -755,6 +755,28 @@ EXPORT_SYMBOL(inet_stream_connect);
|
||||
|
||||
void __inet_accept(struct socket *sock, struct socket *newsock, struct sock *newsk)
|
||||
{
|
||||
/* TODO: use sk_clone_lock() in SCTP and remove protocol checks */
|
||||
if (mem_cgroup_sockets_enabled &&
|
||||
(!IS_ENABLED(CONFIG_IP_SCTP) || sk_is_tcp(newsk))) {
|
||||
gfp_t gfp = GFP_KERNEL | __GFP_NOFAIL;
|
||||
|
||||
mem_cgroup_sk_alloc(newsk);
|
||||
|
||||
if (mem_cgroup_from_sk(newsk)) {
|
||||
int amt;
|
||||
|
||||
/* The socket has not been accepted yet, no need
|
||||
* to look at newsk->sk_wmem_queued.
|
||||
*/
|
||||
amt = sk_mem_pages(newsk->sk_forward_alloc +
|
||||
atomic_read(&newsk->sk_rmem_alloc));
|
||||
if (amt)
|
||||
mem_cgroup_sk_charge(newsk, amt, gfp);
|
||||
}
|
||||
|
||||
kmem_cache_charge(newsk, gfp);
|
||||
}
|
||||
|
||||
sock_rps_record_flow(newsk);
|
||||
WARN_ON(!((1 << newsk->sk_state) &
|
||||
(TCPF_ESTABLISHED | TCPF_SYN_RECV |
|
||||
|
||||
@@ -712,31 +712,6 @@ struct sock *inet_csk_accept(struct sock *sk, struct proto_accept_arg *arg)
|
||||
|
||||
release_sock(sk);
|
||||
|
||||
if (mem_cgroup_sockets_enabled) {
|
||||
gfp_t gfp = GFP_KERNEL | __GFP_NOFAIL;
|
||||
int amt = 0;
|
||||
|
||||
/* atomically get the memory usage, set and charge the
|
||||
* newsk->sk_memcg.
|
||||
*/
|
||||
lock_sock(newsk);
|
||||
|
||||
mem_cgroup_sk_alloc(newsk);
|
||||
if (mem_cgroup_from_sk(newsk)) {
|
||||
/* The socket has not been accepted yet, no need
|
||||
* to look at newsk->sk_wmem_queued.
|
||||
*/
|
||||
amt = sk_mem_pages(newsk->sk_forward_alloc +
|
||||
atomic_read(&newsk->sk_rmem_alloc));
|
||||
}
|
||||
|
||||
if (amt)
|
||||
mem_cgroup_sk_charge(newsk, amt, gfp);
|
||||
kmem_cache_charge(newsk, gfp);
|
||||
|
||||
release_sock(newsk);
|
||||
}
|
||||
|
||||
if (req)
|
||||
reqsk_put(req);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user