ANDROID: cgroup: Fix cgroup_root backport padding calculation

ANDROID_BACKPORT_USE_ARRAY() needs to reserve enough space to fit a
struct rcu_head at a minimum, and it reserves enough space for
CGROUP_SUBSYS_COUNT atomic_ts.

This works well on kernel configurations where the number of
CGROUP_SUBSYS_COUNT is big enough to cause more space than what is
needed for struct rcu_head to be reserved. However, for kernel
configurations where CGROUP_SUBSYS_COUNT is too small and doesn't
reserve enough space, the following build error is triggered:

error: static assertion failed due to requirement
'sizeof(struct cgroup_root::(unnamed ...) <= sizeof(struct cgroup_root::(unnamed at ...))':
struct callback_head rcu is larger than u8 __attribute__((__aligned__(8))) android_backport_reserved1[CGROUP_SUBSYS_COUNT * sizeof(atomic_t)]

Instead of assuming CGROUP_SUBSYS_COUNT is large enough, given that the
minimum size if the size of struct rcu_head, always make sure that
much space is reserved if CGROUP_SUBSYS_COUNT is too small.

Bug: 422866230
Fixes: d66e9166bf ("ANDROID: fix ABI-break in struct cgroup_root")
Change-Id: Ib34c9249c05c4ecfbf9c6d18b613afdd7dff5cb2
Signed-off-by: Isaac J. Manjarres <isaacmanjarres@google.com>
This commit is contained in:
Isaac J. Manjarres
2025-06-06 01:59:54 +00:00
committed by Treehugger Robot
parent 452d899d2f
commit c6325b075d

View File

@@ -41,6 +41,24 @@ struct poll_table_struct;
/* define the enumeration of all cgroup subsystems */
#define SUBSYS(_x) _x ## _cgrp_id,
#define CSS_COUNTERS_SIZE (CGROUP_SUBSYS_COUNT * sizeof(atomic_t))
/*
* This should just use max(), but max() doesn't work in struct definitions.
*
* Originally, the space was reserved for per cgroup subsystem counters, where each counter was
* the size of an atomic_t variable. However, it was later reused to fit a struct rcu_head
* which is why the calculation considers the size of struct rcu_head.
*
* This macro is provided to ANDROID_BACKPORT_USE_ARRAY() which needs to reserve at least
* enough memory to accommodate struct rcu_head. However, if we only reserve CSS_COUNTERS_SIZE,
* that may not be enough space on kernels with a small amount of cgroup subsystems enabled. So,
* we take the max between the two values to use in ANDROID_BACKPORT_USE_ARRAY().
*/
#define CGROUP_ROOT_BACKPORT_PADDING_SIZE \
(CSS_COUNTERS_SIZE > sizeof(struct rcu_head) ? CSS_COUNTERS_SIZE : sizeof(struct rcu_head))
enum cgroup_subsys_id {
#include <linux/cgroup_subsys.h>
CGROUP_SUBSYS_COUNT,
@@ -585,8 +603,12 @@ struct cgroup_root {
/* The name for this hierarchy - may be empty */
char name[MAX_CGROUP_ROOT_NAMELEN];
ANDROID_BACKPORT_USE_ARRAY(1, CGROUP_SUBSYS_COUNT * sizeof(atomic_t),
struct rcu_head rcu);
/* Use the original calculation to preserve the CRC value for the ABI. */
#ifndef __GENKSYMS__
ANDROID_BACKPORT_USE_ARRAY(1, CGROUP_ROOT_BACKPORT_PADDING_SIZE, struct rcu_head rcu);
#else
ANDROID_BACKPORT_USE_ARRAY(1, CGROUP_SUBSYS_COUNT * sizeof(atomic_t), struct rcu_head rcu);
#endif
};
/*