mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
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>
This commit is contained in:
@@ -111,6 +111,7 @@ struct ns_common {
|
||||
u64 ns_id;
|
||||
struct /* global namespace rbtree and list */ {
|
||||
struct rb_node ns_unified_tree_node;
|
||||
struct list_head ns_unified_list_node;
|
||||
};
|
||||
struct /* per type rbtree and list */ {
|
||||
struct rb_node ns_tree_node;
|
||||
@@ -224,6 +225,7 @@ static __always_inline bool is_initial_namespace(struct ns_common *ns)
|
||||
.ns_list_node = LIST_HEAD_INIT(nsname.ns.ns_list_node), \
|
||||
.ns_owner_entry = LIST_HEAD_INIT(nsname.ns.ns_owner_entry), \
|
||||
.ns_owner = LIST_HEAD_INIT(nsname.ns.ns_owner), \
|
||||
.ns_unified_list_node = LIST_HEAD_INIT(nsname.ns.ns_unified_list_node), \
|
||||
}
|
||||
|
||||
#define ns_common_init(__ns) \
|
||||
|
||||
@@ -65,6 +65,7 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
|
||||
RB_CLEAR_NODE(&ns->ns_unified_tree_node);
|
||||
RB_CLEAR_NODE(&ns->ns_owner_tree_node);
|
||||
INIT_LIST_HEAD(&ns->ns_list_node);
|
||||
INIT_LIST_HEAD(&ns->ns_unified_list_node);
|
||||
ns->ns_owner_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&ns->ns_owner);
|
||||
INIT_LIST_HEAD(&ns->ns_owner_entry);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user