summaryrefslogtreecommitdiff
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2025-01-09 11:22:28 +0000
committerMark Brown <broonie@kernel.org>2025-01-09 11:22:28 +0000
commit5640fd07b90ed43225704fecfbbda9d402dba1cf (patch)
tree7c9e9e13681499882d3c5d710e37b2f3b088e831 /net/core/net_namespace.c
parenta38509fd5cdc125ef54562760a05c68ebd4812bc (diff)
parent9d89551994a430b50c4fffcb1e617a057fa76e20 (diff)
spi: Merge up v6.13-rc6
This fixes the i.MX6 and newer Meson platforms in my CI.
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index ae34ac818cda..b5cd3ae4f04c 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -449,6 +449,21 @@ out_free:
goto out;
}
+static LLIST_HEAD(defer_free_list);
+
+static void net_complete_free(void)
+{
+ struct llist_node *kill_list;
+ struct net *net, *next;
+
+ /* Get the list of namespaces to free from last round. */
+ kill_list = llist_del_all(&defer_free_list);
+
+ llist_for_each_entry_safe(net, next, kill_list, defer_free_list)
+ kmem_cache_free(net_cachep, net);
+
+}
+
static void net_free(struct net *net)
{
if (refcount_dec_and_test(&net->passive)) {
@@ -457,7 +472,8 @@ static void net_free(struct net *net)
/* There should not be any trackers left there. */
ref_tracker_dir_exit(&net->notrefcnt_tracker);
- kmem_cache_free(net_cachep, net);
+ /* Wait for an extra rcu_barrier() before final free. */
+ llist_add(&net->defer_free_list, &defer_free_list);
}
}
@@ -642,6 +658,8 @@ static void cleanup_net(struct work_struct *work)
*/
rcu_barrier();
+ net_complete_free();
+
/* Finally it is safe to free my network namespace structure */
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
list_del_init(&net->exit_list);