hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IA7HMV
--------------------------------
Commit 02ebfdc9f2bd ("[Backport] cgroup: Make operations on the cgroup root_list RCU safe") added rcu member to struct cgroup_root, which broke KABI. To keep KABI, add cgroup_root_ext.
Fixes: 02ebfdc9f2bd ("[Backport] cgroup: Make operations on the cgroup root_list RCU safe") Signed-off-by: Chen Ridong chenridong@huawei.com --- include/linux/cgroup-defs.h | 16 ++++++++++++---- kernel/cgroup/cgroup-v1.c | 6 ++++-- kernel/cgroup/cgroup.c | 5 ++++- 3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 196d801d74b6..36103ca580dc 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -526,10 +526,6 @@ 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; /* Must be near the top */ - /* The root cgroup. Root is destroyed on its release. */ struct cgroup cgrp;
@@ -542,6 +538,9 @@ struct cgroup_root { /* Wait while cgroups are being destroyed */ wait_queue_head_t wait;
+ /* A list running through the active hierarchies */ + struct list_head root_list; + /* Hierarchy-specific flags */ unsigned int flags;
@@ -557,6 +556,15 @@ struct cgroup_root { KABI_RESERVE(4) };
+/* + * To keep kabi uncharged, add cgroup_root_ext, add rcu_head to make operations + * on the cgroup root_list RCU safe + */ +struct cgroup_root_ext { + struct rcu_head rcu; /* Must be near the top */ + struct cgroup_root root; +}; + /* * struct cftype: handler definitions for cgroup control files * diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 879813117556..c8500c3a9340 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -1143,6 +1143,7 @@ static int cgroup1_root_to_use(struct fs_context *fc) { struct cgroup_fs_context *ctx = cgroup_fc2context(fc); struct cgroup_root *root; + struct cgroup_root_ext *root_ext; struct cgroup_subsys *ss; int i, ret;
@@ -1215,10 +1216,11 @@ static int cgroup1_root_to_use(struct fs_context *fc) if (ctx->ns != &init_cgroup_ns) return -EPERM;
- root = kzalloc(sizeof(*root), GFP_KERNEL); - if (!root) + root_ext = kzalloc(sizeof(struct cgroup_root_ext), GFP_KERNEL); + if (!root_ext) return -ENOMEM;
+ root = &root_ext->root; ctx->root = root; init_cgroup_root(ctx);
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 48997f20636c..34647f8d6778 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1310,7 +1310,10 @@ static void cgroup_exit_root_id(struct cgroup_root *root)
void cgroup_free_root(struct cgroup_root *root) { - kfree_rcu(root, rcu); + struct cgroup_root_ext *root_ext; + + root_ext = container_of(root, struct cgroup_root_ext, root); + kfree_rcu(root_ext, rcu); }
static void cgroup_destroy_root(struct cgroup_root *root)