From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4718275B0D; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838569; cv=none; b=tRkaN9OfJqzixbbdnlA99s8BFYryfK/A6/RBwkXnMk+gA9AzIgI6QXs3SRLZwRo9rWMLzIFguYioMLrY4B4S3J3j+j1Gb4DrKg9E8XVRJ+PeB0XFx/PxV/oygwdPmDicVpfj4Fain6IRCAu0ViVnwe9bzHohmRpHytSR3Md40F8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838569; c=relaxed/simple; bh=+WRmkSfQGtmlo9na2It4vpTsg5vAymd2N8s4FQH9ZHE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qJIJL/Z7aG+KKS8ftB5ohsdbR1ZlxTYMc6wTLI9o6QbOUJHgzd2Qu9Uf2q5zYO0EaE6wXIpiXKivLBsFH4GnJ9fRfLxq/2fSQ+VVcivsiSZIHYt+PxAdhIdSHyl+gVGbX4IwLJjcri2uz0KImom/E5OwDpI+58n7Kah12bUkjHM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FYW36a0h; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FYW36a0h" Received: by smtp.kernel.org (Postfix) with ESMTPS id 553FBC116B1; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755838568; bh=+WRmkSfQGtmlo9na2It4vpTsg5vAymd2N8s4FQH9ZHE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FYW36a0hVe/L1EObW2wNr+Kb+a4bx4yDsUD423cKa0KLTdfXOuo3O+pRpoXJUVnzQ 42JYpIJlgYHpqtU1R1JSTr+k1EvFYMX7DdZvfBCdVlSP8HkodO0h3+YqBR12P1bbSo MoNp8Wk+IL2kGKDPNsKM4WFbIK1m0OmHhwEuxYl58ryhbyl7BssIJRQT1OD6e7TNoX QPoBMipd1i/FKs8PLgV2EbyUcAJszhhKTnmw+tXLJpqpVMRIqZguHc4h66671xMNWb 3jMJ4uoCZ3jhfEYBHJ+zlWkJYa505+UvJjW6/gaYweFjtqLOWc0cO8VIkO0nRxNRqy YNbU+bKooX9Nw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46292CA0EEB; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) From: Dmitry Safonov via B4 Relay Date: Fri, 22 Aug 2025 05:55:37 +0100 Subject: [PATCH net-next 2/2] tcp: Free TCP-AO/TCP-MD5 info/keys without RCU Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-2-25825d085dcb@arista.com> References: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> In-Reply-To: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> To: Eric Dumazet , Neal Cardwell , Kuniyuki Iwashima , "David S. Miller" , David Ahern , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Bob Gilligan , Salam Noureddine , Dmitry Safonov <0x7f454c46@gmail.com>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Dmitry Safonov X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1755838557; l=4311; i=dima@arista.com; s=20250521; h=from:subject:message-id; bh=DTvDhQjie0nLc2vujkcuQmUlaLvJCsq+rW5VIp5uDdU=; b=BksfMbbtCwVQpxUCwvcI29WnXVacYK7bsGtS784QxTI5NoztdZ6jGs5sdQenKaqOmqV1hBK1B xs8S/UcQKpBAm7GEE849O6RzG06SBL1NeAXCVnca3CXCy9WSVGTr76k X-Developer-Key: i=dima@arista.com; a=ed25519; pk=/z94x2T59rICwjRqYvDsBe0MkpbkkdYrSW2J1G2gIcU= X-Endpoint-Received: by B4 Relay for dima@arista.com/20250521 with auth_id=405 X-Original-From: Dmitry Safonov Reply-To: dima@arista.com From: Dmitry Safonov Now that the destruction of info/keys is delayed until the socket destructor, it's safe to use kfree() without an RCU callback. As either socket was yet in TCP_CLOSE state or the socket refcounter is zero and no one can discover it anymore, it's safe to release memory straight away. Similar thing was possible for twsk already. Signed-off-by: Dmitry Safonov --- net/ipv4/tcp.c | 19 +++---------------- net/ipv4/tcp_ao.c | 5 ++--- net/ipv4/tcp_ipv4.c | 4 ++-- net/ipv4/tcp_minisocks.c | 19 +++++-------------- 4 files changed, 12 insertions(+), 35 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4e996e937e8e5f0e75764caa24240e25006deece..de10d38116a205863c290470fa0cbbddeb8d709e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -412,30 +412,17 @@ static u64 tcp_compute_delivery_rate(const struct tcp_sock *tp) return rate64; } -#ifdef CONFIG_TCP_MD5SIG -static void tcp_md5sig_info_free_rcu(struct rcu_head *head) -{ - struct tcp_md5sig_info *md5sig; - - md5sig = container_of(head, struct tcp_md5sig_info, rcu); - kfree(md5sig); - static_branch_slow_dec_deferred(&tcp_md5_needed); - tcp_md5_release_sigpool(); -} -#endif - static void tcp_destruct_sock(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); #ifdef CONFIG_TCP_MD5SIG if (tp->md5sig_info) { - struct tcp_md5sig_info *md5sig; - md5sig = rcu_dereference_protected(tp->md5sig_info, 1); tcp_clear_md5_list(sk); - call_rcu(&md5sig->rcu, tcp_md5sig_info_free_rcu); - rcu_assign_pointer(tp->md5sig_info, NULL); + kfree(rcu_replace_pointer(tp->md5sig_info, NULL, 1)); + static_branch_slow_dec_deferred(&tcp_md5_needed); + tcp_md5_release_sigpool(); } #endif tcp_ao_destroy_sock(sk, false); diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c index bbb8d5f0eae7d3d8887da3fa4d68e248af9060ad..31302be78bc4450b56fa23a390b6d03b2262741d 100644 --- a/net/ipv4/tcp_ao.c +++ b/net/ipv4/tcp_ao.c @@ -268,9 +268,8 @@ static void tcp_ao_key_free_rcu(struct rcu_head *head) kfree_sensitive(key); } -static void tcp_ao_info_free_rcu(struct rcu_head *head) +static void tcp_ao_info_free(struct tcp_ao_info *ao) { - struct tcp_ao_info *ao = container_of(head, struct tcp_ao_info, rcu); struct tcp_ao_key *key; struct hlist_node *n; @@ -310,7 +309,7 @@ void tcp_ao_destroy_sock(struct sock *sk, bool twsk) if (!twsk) tcp_ao_sk_omem_free(sk, ao); - call_rcu(&ao->rcu, tcp_ao_info_free_rcu); + tcp_ao_info_free(ao); } void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 32814f205fdfdcbd4be4765a4e127c8f175d3b14..185d16ff2d0ad7b20e2404ceff71cccaff4ed4bc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1505,9 +1505,9 @@ void tcp_clear_md5_list(struct sock *sk) md5sig = rcu_dereference_protected(tp->md5sig_info, 1); hlist_for_each_entry_safe(key, n, &md5sig->head, node) { - hlist_del_rcu(&key->node); + hlist_del(&key->node); atomic_sub(sizeof(*key), &sk->sk_omem_alloc); - kfree_rcu(key, rcu); + kfree(key); } } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 2994c9222c9cb5ee86b60bdb553f92130e52c70e..c93812b19893742b071b0f7a49c4293a781e8de4 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -377,26 +377,17 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) } EXPORT_SYMBOL(tcp_time_wait); -#ifdef CONFIG_TCP_MD5SIG -static void tcp_md5_twsk_free_rcu(struct rcu_head *head) -{ - struct tcp_md5sig_key *key; - - key = container_of(head, struct tcp_md5sig_key, rcu); - kfree(key); - static_branch_slow_dec_deferred(&tcp_md5_needed); - tcp_md5_release_sigpool(); -} -#endif - void tcp_twsk_destructor(struct sock *sk) { #ifdef CONFIG_TCP_MD5SIG if (static_branch_unlikely(&tcp_md5_needed.key)) { struct tcp_timewait_sock *twsk = tcp_twsk(sk); - if (twsk->tw_md5_key) - call_rcu(&twsk->tw_md5_key->rcu, tcp_md5_twsk_free_rcu); + if (twsk->tw_md5_key) { + kfree(twsk->tw_md5_key); + static_branch_slow_dec_deferred(&tcp_md5_needed); + tcp_md5_release_sigpool(); + } } #endif tcp_ao_destroy_sock(sk, true); -- 2.42.2