diff options
| author | Christian Brauner <brauner@kernel.org> | 2025-10-29 13:20:31 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2025-11-03 17:41:18 +0100 |
| commit | 560e25e70fa40ec69f97f14207bde9bc18bec9b8 (patch) | |
| tree | cd7d45f1833f36d0a586bd6d575ef53ddda6c76f /kernel/nstree.c | |
| parent | a202a50092cc47ff63048f0a53530fb95bbf3e44 (diff) | |
nstree: add unified namespace list
Allow to walk the unified namespace list completely locklessly.
Link: https://patch.msgid.link/20251029-work-namespace-nstree-listns-v4-18-2e6f823ebdc0@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'kernel/nstree.c')
| -rw-r--r-- | kernel/nstree.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/nstree.c b/kernel/nstree.c index 419d500d09df..dcad6a308547 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -9,6 +9,7 @@ static __cacheline_aligned_in_smp DEFINE_SEQLOCK(ns_tree_lock); static struct rb_root ns_unified_tree = RB_ROOT; /* protected by ns_tree_lock */ +static LIST_HEAD(ns_unified_list); /* protected by ns_tree_lock */ /** * struct ns_tree - Namespace tree @@ -137,7 +138,13 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree) else list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node); + /* Add to unified tree and list */ rb_find_add_rcu(&ns->ns_unified_tree_node, &ns_unified_tree, ns_cmp_unified); + prev = rb_prev(&ns->ns_unified_tree_node); + if (!prev) + list_add_rcu(&ns->ns_unified_list_node, &ns_unified_list); + else + list_add_rcu(&ns->ns_unified_list_node, &node_to_ns_unified(prev)->ns_unified_list_node); if (ops) { struct user_namespace *user_ns; @@ -186,11 +193,15 @@ void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree) write_seqlock(&ns_tree_lock); rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree); - rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); RB_CLEAR_NODE(&ns->ns_tree_node); list_bidir_del_rcu(&ns->ns_list_node); + rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); + RB_CLEAR_NODE(&ns->ns_unified_tree_node); + + list_bidir_del_rcu(&ns->ns_unified_list_node); + /* Remove from owner's rbtree if this namespace has an owner */ if (ops) { user_ns = ops->owner(ns); |
