| From ec2fd51161ae592dc7f8dbb4c252e5517e27c498 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 26 Mar 2025 18:36:32 +0100 |
| Subject: net: decrease cached dst counters in dst_release |
| |
| From: Antoine Tenart <atenart@kernel.org> |
| |
| [ Upstream commit 3a0a3ff6593d670af2451ec363ccb7b18aec0c0a ] |
| |
| Upstream fix ac888d58869b ("net: do not delay dst_entries_add() in |
| dst_release()") moved decrementing the dst count from dst_destroy to |
| dst_release to avoid accessing already freed data in case of netns |
| dismantle. However in case CONFIG_DST_CACHE is enabled and OvS+tunnels |
| are used, this fix is incomplete as the same issue will be seen for |
| cached dsts: |
| |
| Unable to handle kernel paging request at virtual address ffff5aabf6b5c000 |
| Call trace: |
| percpu_counter_add_batch+0x3c/0x160 (P) |
| dst_release+0xec/0x108 |
| dst_cache_destroy+0x68/0xd8 |
| dst_destroy+0x13c/0x168 |
| dst_destroy_rcu+0x1c/0xb0 |
| rcu_do_batch+0x18c/0x7d0 |
| rcu_core+0x174/0x378 |
| rcu_core_si+0x18/0x30 |
| |
| Fix this by invalidating the cache, and thus decrementing cached dst |
| counters, in dst_release too. |
| |
| Fixes: d71785ffc7e7 ("net: add dst_cache to ovs vxlan lwtunnel") |
| Signed-off-by: Antoine Tenart <atenart@kernel.org> |
| Link: https://patch.msgid.link/20250326173634.31096-1-atenart@kernel.org |
| Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/core/dst.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| diff --git a/net/core/dst.c b/net/core/dst.c |
| index 137b8d1c72203..aad197e761cb4 100644 |
| --- a/net/core/dst.c |
| +++ b/net/core/dst.c |
| @@ -167,6 +167,14 @@ static void dst_count_dec(struct dst_entry *dst) |
| void dst_release(struct dst_entry *dst) |
| { |
| if (dst && rcuref_put(&dst->__rcuref)) { |
| +#ifdef CONFIG_DST_CACHE |
| + if (dst->flags & DST_METADATA) { |
| + struct metadata_dst *md_dst = (struct metadata_dst *)dst; |
| + |
| + if (md_dst->type == METADATA_IP_TUNNEL) |
| + dst_cache_reset_now(&md_dst->u.tun_info.dst_cache); |
| + } |
| +#endif |
| dst_count_dec(dst); |
| call_rcu_hurry(&dst->rcu_head, dst_destroy_rcu); |
| } |
| -- |
| 2.39.5 |
| |