Unverified Commit 560e25e7 authored by Christian Brauner's avatar Christian Brauner
Browse files

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: default avatarChristian Brauner <brauner@kernel.org>
parent a202a500
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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)                     \
+1 −0
Original line number Diff line number Diff line
@@ -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);
+12 −1
Original line number Diff line number Diff line
@@ -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);