From: Greg Kroah-Hartman Date: Mon, 2 Dec 2024 13:14:55 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.19.325~94 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0f96a72a6c74f3aac14f99fe3d845034a22f1ac3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: cgroup-make-operations-on-the-cgroup-root_list-rcu-safe.patch cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch --- diff --git a/queue-5.4/cgroup-make-operations-on-the-cgroup-root_list-rcu-safe.patch b/queue-5.4/cgroup-make-operations-on-the-cgroup-root_list-rcu-safe.patch new file mode 100644 index 00000000000..6aef19f6646 --- /dev/null +++ b/queue-5.4/cgroup-make-operations-on-the-cgroup-root_list-rcu-safe.patch @@ -0,0 +1,131 @@ +From stable+bounces-95988-greg=kroah.com@vger.kernel.org Mon Dec 2 12:11:04 2024 +From: Siddh Raman Pant +Date: Mon, 2 Dec 2024 16:40:23 +0530 +Subject: cgroup: Make operations on the cgroup root_list RCU safe +To: Greg Kroah-Hartman +Cc: stable , linux-kernel +Message-ID: <20241202111024.11212-2-siddh.raman.pant@oracle.com> + +From: Yafang Shao + +commit d23b5c577715892c87533b13923306acc6243f93 upstream. + +At present, when we perform operations on the cgroup root_list, we must +hold the cgroup_mutex, which is a relatively heavyweight lock. In reality, +we can make operations on this list RCU-safe, eliminating the need to hold +the cgroup_mutex during traversal. Modifications to the list only occur in +the cgroup root setup and destroy paths, which should be infrequent in a +production environment. In contrast, traversal may occur frequently. +Therefore, making it RCU-safe would be beneficial. + +Signed-off-by: Yafang Shao +Signed-off-by: Tejun Heo +[fp: adapt to 5.10 mainly because of changes made by e210a89f5b07 + ("cgroup.c: add helper __cset_cgroup_from_root to cleanup duplicated + codes")] +Signed-off-by: Fedor Pchelkin +[Shivani: Modified to apply on v5.4.y] +Signed-off-by: Shivani Agarwal +Reviewed-by: Siddh Raman Pant +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cgroup-defs.h | 1 + + kernel/cgroup/cgroup-internal.h | 3 ++- + kernel/cgroup/cgroup.c | 23 ++++++++++++++++------- + 3 files changed, 19 insertions(+), 8 deletions(-) + +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -517,6 +517,7 @@ struct cgroup_root { + + /* A list running through the active hierarchies */ + struct list_head root_list; ++ struct rcu_head rcu; + + /* Hierarchy-specific flags */ + unsigned int flags; +--- a/kernel/cgroup/cgroup-internal.h ++++ b/kernel/cgroup/cgroup-internal.h +@@ -172,7 +172,8 @@ extern struct list_head cgroup_roots; + + /* iterate across the hierarchies */ + #define for_each_root(root) \ +- list_for_each_entry((root), &cgroup_roots, root_list) ++ list_for_each_entry_rcu((root), &cgroup_roots, root_list, \ ++ lockdep_is_held(&cgroup_mutex)) + + /** + * for_each_subsys - iterate all enabled cgroup subsystems +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -1314,7 +1314,7 @@ void cgroup_free_root(struct cgroup_root + { + if (root) { + idr_destroy(&root->cgroup_idr); +- kfree(root); ++ kfree_rcu(root, rcu); + } + } + +@@ -1348,7 +1348,7 @@ static void cgroup_destroy_root(struct c + spin_unlock_irq(&css_set_lock); + + if (!list_empty(&root->root_list)) { +- list_del(&root->root_list); ++ list_del_rcu(&root->root_list); + cgroup_root_count--; + } + +@@ -1401,7 +1401,6 @@ static struct cgroup *cset_cgroup_from_r + { + struct cgroup *res = NULL; + +- lockdep_assert_held(&cgroup_mutex); + lockdep_assert_held(&css_set_lock); + + if (cset == &init_css_set) { +@@ -1421,13 +1420,23 @@ static struct cgroup *cset_cgroup_from_r + } + } + +- BUG_ON(!res); ++ /* ++ * If cgroup_mutex is not held, the cgrp_cset_link will be freed ++ * before we remove the cgroup root from the root_list. Consequently, ++ * when accessing a cgroup root, the cset_link may have already been ++ * freed, resulting in a NULL res_cgroup. However, by holding the ++ * cgroup_mutex, we ensure that res_cgroup can't be NULL. ++ * If we don't hold cgroup_mutex in the caller, we must do the NULL ++ * check. ++ */ + return res; + } + + /* + * Return the cgroup for "task" from the given hierarchy. Must be +- * called with cgroup_mutex and css_set_lock held. ++ * called with css_set_lock held to prevent task's groups from being modified. ++ * Must be called with either cgroup_mutex or rcu read lock to prevent the ++ * cgroup root from being destroyed. + */ + struct cgroup *task_cgroup_from_root(struct task_struct *task, + struct cgroup_root *root) +@@ -2012,7 +2021,7 @@ void init_cgroup_root(struct cgroup_fs_c + struct cgroup_root *root = ctx->root; + struct cgroup *cgrp = &root->cgrp; + +- INIT_LIST_HEAD(&root->root_list); ++ INIT_LIST_HEAD_RCU(&root->root_list); + atomic_set(&root->nr_cgrps, 1); + cgrp->root = root; + init_cgroup_housekeeping(cgrp); +@@ -2094,7 +2103,7 @@ int cgroup_setup_root(struct cgroup_root + * care of subsystems' refcounts, which are explicitly dropped in + * the failure exit path. + */ +- list_add(&root->root_list, &cgroup_roots); ++ list_add_rcu(&root->root_list, &cgroup_roots); + cgroup_root_count++; + + /* diff --git a/queue-5.4/cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch b/queue-5.4/cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch new file mode 100644 index 00000000000..36a17a93d30 --- /dev/null +++ b/queue-5.4/cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch @@ -0,0 +1,71 @@ +From stable+bounces-95989-greg=kroah.com@vger.kernel.org Mon Dec 2 12:11:20 2024 +From: Siddh Raman Pant +Date: Mon, 2 Dec 2024 16:40:24 +0530 +Subject: cgroup: Move rcu_head up near the top of cgroup_root +To: Greg Kroah-Hartman +Cc: stable , linux-kernel +Message-ID: <20241202111024.11212-3-siddh.raman.pant@oracle.com> + +From: Waiman Long + +commit a7fb0423c201ba12815877a0b5a68a6a1710b23a upstream. + +Commit d23b5c577715 ("cgroup: Make operations on the cgroup root_list RCU +safe") adds a new rcu_head to the cgroup_root structure and kvfree_rcu() +for freeing the cgroup_root. + +The current implementation of kvfree_rcu(), however, has the limitation +that the offset of the rcu_head structure within the larger data +structure must be less than 4096 or the compilation will fail. See the +macro definition of __is_kvfree_rcu_offset() in include/linux/rcupdate.h +for more information. + +By putting rcu_head below the large cgroup structure, any change to the +cgroup structure that makes it larger run the risk of causing build +failure under certain configurations. Commit 77070eeb8821 ("cgroup: +Avoid false cacheline sharing of read mostly rstat_cpu") happens to be +the last straw that breaks it. Fix this problem by moving the rcu_head +structure up before the cgroup structure. + +Fixes: d23b5c577715 ("cgroup: Make operations on the cgroup root_list RCU safe") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/lkml/20231207143806.114e0a74@canb.auug.org.au/ +Signed-off-by: Waiman Long +Acked-by: Yafang Shao +Reviewed-by: Yosry Ahmed +Reviewed-by: Michal Koutný +Signed-off-by: Tejun Heo +Signed-off-by: Fedor Pchelkin +[Shivani: Modified to apply on v5.4.y] +Signed-off-by: Shivani Agarwal +Reviewed-by: Siddh Raman Pant +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cgroup-defs.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -506,6 +506,10 @@ struct cgroup_root { + /* Unique id for this hierarchy. */ + int hierarchy_id; + ++ /* A list running through the active hierarchies */ ++ struct list_head root_list; ++ struct rcu_head rcu; ++ + /* The root cgroup. Root is destroyed on its release. */ + struct cgroup cgrp; + +@@ -515,10 +519,6 @@ struct cgroup_root { + /* Number of cgroups in the hierarchy, used only for /proc/cgroups */ + atomic_t nr_cgrps; + +- /* A list running through the active hierarchies */ +- struct list_head root_list; +- struct rcu_head rcu; +- + /* Hierarchy-specific flags */ + unsigned int flags; + diff --git a/queue-5.4/series b/queue-5.4/series index 5e7266966e8..c9727c3b141 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -142,3 +142,5 @@ staging-greybus-uart-clean-up-tiocgserial.patch staging-greybus-uart-fix-atomicity-violation-in-get_.patch apparmor-fix-do-simple-duplicate-message-elimination.patch usb-ehci-spear-fix-call-balance-of-sehci-clk-handling-routines.patch +cgroup-make-operations-on-the-cgroup-root_list-rcu-safe.patch +cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch