Blob Blame History Raw
From: Michal Koutný <mkoutny@suse.com>
Date: Thu, 21 Jul 2022 19:09:50 +0200
Subject: KABI: cgroup: Restore KABI of css_set
Patch-mainline: Never, SLES KABI fix
References: bsc#1201610

This is precautionary KABI fix. No sane module should look into the layout of
struct css_set.
No exported symbol relies on the struct css_set layout, the structure is
reachable only indirectly via (several) pointers.
It is allocated/freed by our kernel code only.

The only possible issue would be inlined functions that dereference structure's
members (task_css_is_root, task_dfl_cgroup). The upstream patch inserts a new
member in the middle, however, after members used by these inlined functions.

For strict KABI compatibility (this KABI patch could be unnecessary with the
reasoning above), move the new members to the end:
  a) to keep the layout backwards compatible,
  b) keep the old mg_preload_node in the middle as a dummy.

---
 include/linux/cgroup-defs.h |    8 ++++++--
 kernel/cgroup/cgroup.c      |    6 ++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -203,9 +203,9 @@ struct css_set {
 	/*
 	 * List of csets participating in the on-going migration either as
 	 * source or destination.  Protected by cgroup_mutex.
+	 * mg_preload_node is unused (kept for KABI, see real nodes at the end)
 	 */
-	struct list_head mg_src_preload_node;
-	struct list_head mg_dst_preload_node;
+	struct list_head mg_preload_node;
 	struct list_head mg_node;
 
 	/*
@@ -224,6 +224,10 @@ struct css_set {
 
 	/* For RCU-protected deletion */
 	struct rcu_head rcu_head;
+#ifndef __GENKSYMS__
+	struct list_head mg_src_preload_node;
+	struct list_head mg_dst_preload_node;
+#endif
 };
 
 struct cgroup {
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -545,9 +545,10 @@ struct css_set init_css_set = {
 	.mg_tasks		= LIST_HEAD_INIT(init_css_set.mg_tasks),
 	.task_iters		= LIST_HEAD_INIT(init_css_set.task_iters),
 	.cgrp_links		= LIST_HEAD_INIT(init_css_set.cgrp_links),
+	.mg_preload_node	= LIST_HEAD_INIT(init_css_set.mg_preload_node),
+	.mg_node		= LIST_HEAD_INIT(init_css_set.mg_node),
 	.mg_src_preload_node	= LIST_HEAD_INIT(init_css_set.mg_src_preload_node),
 	.mg_dst_preload_node	= LIST_HEAD_INIT(init_css_set.mg_dst_preload_node),
-	.mg_node		= LIST_HEAD_INIT(init_css_set.mg_node),
 };
 
 static int css_set_count	= 1;	/* 1 for init_css_set */
@@ -970,9 +971,10 @@ static struct css_set *find_css_set(stru
 	INIT_LIST_HEAD(&cset->task_iters);
 	INIT_HLIST_NODE(&cset->hlist);
 	INIT_LIST_HEAD(&cset->cgrp_links);
+	INIT_LIST_HEAD(&cset->mg_preload_node);
+	INIT_LIST_HEAD(&cset->mg_node);
 	INIT_LIST_HEAD(&cset->mg_src_preload_node);
 	INIT_LIST_HEAD(&cset->mg_dst_preload_node);
-	INIT_LIST_HEAD(&cset->mg_node);
 
 	/* Copy the set of subsystem state objects generated in
 	 * find_existing_css_set() */