]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ns: don't increment or decrement initial namespaces
authorChristian Brauner <brauner@kernel.org>
Sun, 9 Nov 2025 21:11:23 +0000 (22:11 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 10 Nov 2025 09:20:53 +0000 (10:20 +0100)
There's no need to bump the active reference counts of initial
namespaces as they're always active and can simply remain at 1.

Link: https://patch.msgid.link/20251109-namespace-6-19-fixes-v1-2-ae8a4ad5a3b3@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
include/linux/ns_common.h
kernel/nscommon.c

index bd4492ef6ffc213d94194b7c71b24919b7d9d98c..791b18dc77d07a6b8a43eda3f526780367396b42 100644 (file)
@@ -141,6 +141,12 @@ static __always_inline bool is_initial_namespace(struct ns_common *ns)
                                 IPC_NS_INIT_INO - MNT_NS_INIT_INO + 1));
 }
 
+static __always_inline bool is_ns_init_id(const struct ns_common *ns)
+{
+       VFS_WARN_ON_ONCE(ns->ns_id == 0);
+       return ns->ns_id <= NS_LAST_INIT_ID;
+}
+
 #define to_ns_common(__ns)                                    \
        _Generic((__ns),                                      \
                struct cgroup_namespace *:       &(__ns)->ns, \
@@ -285,14 +291,19 @@ void __ns_ref_active_get_owner(struct ns_common *ns);
 
 static __always_inline void __ns_ref_active_get(struct ns_common *ns)
 {
-       WARN_ON_ONCE(atomic_add_negative(1, &ns->__ns_ref_active));
-       VFS_WARN_ON_ONCE(is_initial_namespace(ns) && __ns_ref_active_read(ns) <= 0);
+       /* Initial namespaces are always active. */
+       if (!is_ns_init_id(ns))
+               WARN_ON_ONCE(atomic_add_negative(1, &ns->__ns_ref_active));
 }
 #define ns_ref_active_get(__ns) \
        do { if (__ns) __ns_ref_active_get(to_ns_common(__ns)); } while (0)
 
 static __always_inline bool __ns_ref_active_get_not_zero(struct ns_common *ns)
 {
+       /* Initial namespaces are always active. */
+       if (is_ns_init_id(ns))
+               return true;
+
        if (atomic_inc_not_zero(&ns->__ns_ref_active)) {
                VFS_WARN_ON_ONCE(!__ns_ref_read(ns));
                return true;
@@ -307,6 +318,10 @@ void __ns_ref_active_put_owner(struct ns_common *ns);
 
 static __always_inline void __ns_ref_active_put(struct ns_common *ns)
 {
+       /* Initial namespaces are always active. */
+       if (is_ns_init_id(ns))
+               return;
+
        if (atomic_dec_and_test(&ns->__ns_ref_active)) {
                VFS_WARN_ON_ONCE(is_initial_namespace(ns));
                VFS_WARN_ON_ONCE(!__ns_ref_read(ns));
@@ -319,8 +334,10 @@ static __always_inline void __ns_ref_active_put(struct ns_common *ns)
 static __always_inline struct ns_common *__must_check ns_get_unless_inactive(struct ns_common *ns)
 {
        VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) && !__ns_ref_read(ns));
-       if (!__ns_ref_active_read(ns))
+       if (!__ns_ref_active_read(ns)) {
+               VFS_WARN_ON_ONCE(is_ns_init_id(ns));
                return NULL;
+       }
        if (!__ns_ref_get(ns))
                return NULL;
        return ns;
index d67ae7ad775919bd71747887c7c73ab74fb94e83..70cb66232e4c0fb9b76b9e4cfc565d6b57bfa071 100644 (file)
@@ -177,6 +177,7 @@ void __ns_ref_active_put_owner(struct ns_common *ns)
                ns = ns_owner(ns);
                if (!ns)
                        return;
+               VFS_WARN_ON_ONCE(is_ns_init_id(ns));
                if (!atomic_dec_and_test(&ns->__ns_ref_active))
                        return;
        }
@@ -276,6 +277,10 @@ void __ns_ref_active_put_owner(struct ns_common *ns)
  */
 void __ns_ref_active_resurrect(struct ns_common *ns)
 {
+       /* Initial namespaces are always active. */
+       if (is_ns_init_id(ns))
+               return;
+
        /* If we didn't resurrect the namespace we're done. */
        if (atomic_fetch_add(1, &ns->__ns_ref_active))
                return;
@@ -289,6 +294,7 @@ void __ns_ref_active_resurrect(struct ns_common *ns)
                if (!ns)
                        return;
 
+               VFS_WARN_ON_ONCE(is_ns_init_id(ns));
                if (atomic_fetch_add(1, &ns->__ns_ref_active))
                        return;
        }