This is a no functional change to hide physical storage of cgroup's
level and it allows subesequent conversion of the storage.
Signed-off-by: Michal Koutný <mkoutny@suse.com>
---
block/bfq-iosched.c | 2 +-
block/blk-iocost.c | 4 ++--
include/linux/cgroup.h | 18 +++++++++++++++---
include/trace/events/cgroup.h | 8 ++++----
kernel/bpf/helpers.c | 2 +-
kernel/cgroup/cgroup.c | 4 ++--
net/netfilter/nft_socket.c | 2 +-
7 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 4a8d3d96bfe49..f293bab068274 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -601,7 +601,7 @@ static bool bfqq_request_over_limit(struct bfq_data *bfqd,
goto out;
/* +1 for bfqq entity, root cgroup not included */
- depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1;
+ depth = cgroup_level(bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup) + 1;
if (depth > alloc_depth) {
spin_unlock_irq(&bfqd->lock);
if (entities != inline_entities)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index a0416927d33dc..b4eebe61dca7f 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -2962,7 +2962,7 @@ static void ioc_cpd_free(struct blkcg_policy_data *cpd)
static struct blkg_policy_data *ioc_pd_alloc(struct gendisk *disk,
struct blkcg *blkcg, gfp_t gfp)
{
- int levels = blkcg->css.cgroup->level + 1;
+ int levels = cgroup_level(blkcg->css.cgroup) + 1;
struct ioc_gq *iocg;
iocg = kzalloc_node(struct_size(iocg, ancestors, levels), gfp,
@@ -3003,7 +3003,7 @@ static void ioc_pd_init(struct blkg_policy_data *pd)
init_waitqueue_head(&iocg->waitq);
hrtimer_setup(&iocg->waitq_timer, iocg_waitq_timer_fn, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
- iocg->level = blkg->blkcg->css.cgroup->level;
+ iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
for (tblkg = blkg; tblkg; tblkg = tblkg->parent) {
struct ioc_gq *tiocg = blkg_to_iocg(tblkg);
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index bc892e3b37eea..0290878ebad26 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -525,6 +525,18 @@ static inline struct cgroup *cgroup_parent(struct cgroup *cgrp)
return NULL;
}
+/**
+ * cgroup_level - cgroup depth
+ * @cgrp: cgroup
+ *
+ * The depth this cgroup is at. The root is at depth zero and each step down
+ * the hierarchy increments the level.
+ */
+static inline int cgroup_level(struct cgroup *cgrp)
+{
+ return cgrp->level;
+}
+
/**
* cgroup_is_descendant - test ancestry
* @cgrp: the cgroup to be tested
@@ -537,9 +549,9 @@ static inline struct cgroup *cgroup_parent(struct cgroup *cgrp)
static inline bool cgroup_is_descendant(struct cgroup *cgrp,
struct cgroup *ancestor)
{
- if (cgrp->root != ancestor->root || cgrp->level < ancestor->level)
+ if (cgrp->root != ancestor->root || cgroup_level(cgrp) < cgroup_level(ancestor))
return false;
- return cgrp->ancestors[ancestor->level] == ancestor;
+ return cgrp->ancestors[cgroup_level(ancestor)] == ancestor;
}
/**
@@ -556,7 +568,7 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp,
static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
int ancestor_level)
{
- if (ancestor_level < 0 || ancestor_level > cgrp->level)
+ if (ancestor_level < 0 || ancestor_level > cgroup_level(cgrp))
return NULL;
return cgrp->ancestors[ancestor_level];
}
diff --git a/include/trace/events/cgroup.h b/include/trace/events/cgroup.h
index ba9229af9a343..0a1bc91754b5e 100644
--- a/include/trace/events/cgroup.h
+++ b/include/trace/events/cgroup.h
@@ -67,7 +67,7 @@ DECLARE_EVENT_CLASS(cgroup,
TP_fast_assign(
__entry->root = cgrp->root->hierarchy_id;
__entry->id = cgroup_id(cgrp);
- __entry->level = cgrp->level;
+ __entry->level = cgroup_level(cgrp);
__assign_str(path);
),
@@ -136,7 +136,7 @@ DECLARE_EVENT_CLASS(cgroup_migrate,
TP_fast_assign(
__entry->dst_root = dst_cgrp->root->hierarchy_id;
__entry->dst_id = cgroup_id(dst_cgrp);
- __entry->dst_level = dst_cgrp->level;
+ __entry->dst_level = cgroup_level(dst_cgrp);
__assign_str(dst_path);
__entry->pid = task->pid;
__assign_str(comm);
@@ -180,7 +180,7 @@ DECLARE_EVENT_CLASS(cgroup_event,
TP_fast_assign(
__entry->root = cgrp->root->hierarchy_id;
__entry->id = cgroup_id(cgrp);
- __entry->level = cgrp->level;
+ __entry->level = cgroup_level(cgrp);
__assign_str(path);
__entry->val = val;
),
@@ -221,7 +221,7 @@ DECLARE_EVENT_CLASS(cgroup_rstat,
TP_fast_assign(
__entry->root = cgrp->root->hierarchy_id;
__entry->id = cgroup_id(cgrp);
- __entry->level = cgrp->level;
+ __entry->level = cgroup_level(cgrp);
__entry->cpu = cpu;
__entry->contended = contended;
),
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index db72b96f9c8c8..b825f6e0a1c29 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -2577,7 +2577,7 @@ __bpf_kfunc struct cgroup *bpf_cgroup_ancestor(struct cgroup *cgrp, int level)
{
struct cgroup *ancestor;
- if (level > cgrp->level || level < 0)
+ if (level > cgroup_level(cgrp) || level < 0)
return NULL;
/* cgrp's refcnt could be 0 here, but ancestors can still be accessed */
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 554a02ee298ba..e011f1dd6d87f 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -5843,7 +5843,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
struct cgroup_root *root = parent->root;
struct cgroup *cgrp, *tcgrp;
struct kernfs_node *kn;
- int i, level = parent->level + 1;
+ int i, level = cgroup_level(parent) + 1;
int ret;
/* allocate the cgroup and its ID, 0 is reserved for the root */
@@ -5884,7 +5884,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
goto out_stat_exit;
for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp))
- cgrp->ancestors[tcgrp->level] = tcgrp;
+ cgrp->ancestors[cgroup_level(tcgrp)] = tcgrp;
/*
* New cgroup inherits effective freeze counter, and
diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c
index 36affbb697c2f..a5b0340924efb 100644
--- a/net/netfilter/nft_socket.c
+++ b/net/netfilter/nft_socket.c
@@ -64,7 +64,7 @@ static noinline int nft_socket_cgroup_subtree_level(void)
if (IS_ERR(cgrp))
return PTR_ERR(cgrp);
- level = cgrp->level;
+ level = cgroup_level(cgrp);
cgroup_put(cgrp);
--
2.52.0
Hi Michal,
kernel test robot noticed the following build errors:
[auto build test ERROR on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]
url: https://github.com/intel-lab-lkp/linux/commits/Michal-Koutn/cgroup-Eliminate-cgrp_ancestor_storage-in-cgroup_root/20251218-004346
base: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link: https://lore.kernel.org/r/20251217162744.352391-3-mkoutny%40suse.com
patch subject: [PATCH 2/4] cgroup: Introduce cgroup_level() helper
config: sparc64-randconfig-r134-20251218 (https://download.01.org/0day-ci/archive/20251220/202512202230.1uoB5chV-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512202230.1uoB5chV-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512202230.1uoB5chV-lkp@intel.com/
All errors (new ones prefixed by >>):
>> block/blk-iocost.c:3006:53: error: expected ';' after expression
3006 | iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
| ^
| ;
1 error generated.
vim +3006 block/blk-iocost.c
2981
2982 static void ioc_pd_init(struct blkg_policy_data *pd)
2983 {
2984 struct ioc_gq *iocg = pd_to_iocg(pd);
2985 struct blkcg_gq *blkg = pd_to_blkg(&iocg->pd);
2986 struct ioc *ioc = q_to_ioc(blkg->q);
2987 struct ioc_now now;
2988 struct blkcg_gq *tblkg;
2989 unsigned long flags;
2990
2991 ioc_now(ioc, &now);
2992
2993 iocg->ioc = ioc;
2994 atomic64_set(&iocg->vtime, now.vnow);
2995 atomic64_set(&iocg->done_vtime, now.vnow);
2996 atomic64_set(&iocg->active_period, atomic64_read(&ioc->cur_period));
2997 INIT_LIST_HEAD(&iocg->active_list);
2998 INIT_LIST_HEAD(&iocg->walk_list);
2999 INIT_LIST_HEAD(&iocg->surplus_list);
3000 iocg->hweight_active = WEIGHT_ONE;
3001 iocg->hweight_inuse = WEIGHT_ONE;
3002
3003 init_waitqueue_head(&iocg->waitq);
3004 hrtimer_setup(&iocg->waitq_timer, iocg_waitq_timer_fn, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
3005
> 3006 iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
3007
3008 for (tblkg = blkg; tblkg; tblkg = tblkg->parent) {
3009 struct ioc_gq *tiocg = blkg_to_iocg(tblkg);
3010 iocg->ancestors[tiocg->level] = tiocg;
3011 }
3012
3013 spin_lock_irqsave(&ioc->lock, flags);
3014 weight_updated(iocg, &now);
3015 spin_unlock_irqrestore(&ioc->lock, flags);
3016 }
3017
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Michal,
kernel test robot noticed the following build errors:
[auto build test ERROR on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]
url: https://github.com/intel-lab-lkp/linux/commits/Michal-Koutn/cgroup-Eliminate-cgrp_ancestor_storage-in-cgroup_root/20251218-004346
base: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link: https://lore.kernel.org/r/20251217162744.352391-3-mkoutny%40suse.com
patch subject: [PATCH 2/4] cgroup: Introduce cgroup_level() helper
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20251221/202512210532.ziNaxDJf-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251221/202512210532.ziNaxDJf-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512210532.ziNaxDJf-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
block/blk-iocost.c: In function 'ioc_pd_init':
>> block/blk-iocost.c:3006:60: error: expected ';' before 'for'
3006 | iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
| ^
| ;
3007 |
3008 | for (tblkg = blkg; tblkg; tblkg = tblkg->parent) {
| ~~~
>> block/blk-iocost.c:2988:26: warning: unused variable 'tblkg' [-Wunused-variable]
2988 | struct blkcg_gq *tblkg;
| ^~~~~
vim +3006 block/blk-iocost.c
2981
2982 static void ioc_pd_init(struct blkg_policy_data *pd)
2983 {
2984 struct ioc_gq *iocg = pd_to_iocg(pd);
2985 struct blkcg_gq *blkg = pd_to_blkg(&iocg->pd);
2986 struct ioc *ioc = q_to_ioc(blkg->q);
2987 struct ioc_now now;
> 2988 struct blkcg_gq *tblkg;
2989 unsigned long flags;
2990
2991 ioc_now(ioc, &now);
2992
2993 iocg->ioc = ioc;
2994 atomic64_set(&iocg->vtime, now.vnow);
2995 atomic64_set(&iocg->done_vtime, now.vnow);
2996 atomic64_set(&iocg->active_period, atomic64_read(&ioc->cur_period));
2997 INIT_LIST_HEAD(&iocg->active_list);
2998 INIT_LIST_HEAD(&iocg->walk_list);
2999 INIT_LIST_HEAD(&iocg->surplus_list);
3000 iocg->hweight_active = WEIGHT_ONE;
3001 iocg->hweight_inuse = WEIGHT_ONE;
3002
3003 init_waitqueue_head(&iocg->waitq);
3004 hrtimer_setup(&iocg->waitq_timer, iocg_waitq_timer_fn, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
3005
> 3006 iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
3007
3008 for (tblkg = blkg; tblkg; tblkg = tblkg->parent) {
3009 struct ioc_gq *tiocg = blkg_to_iocg(tblkg);
3010 iocg->ancestors[tiocg->level] = tiocg;
3011 }
3012
3013 spin_lock_irqsave(&ioc->lock, flags);
3014 weight_updated(iocg, &now);
3015 spin_unlock_irqrestore(&ioc->lock, flags);
3016 }
3017
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
> diff --git a/block/blk-iocost.c b/block/blk-iocost.c
> index a0416927d33d..b4eebe61dca7 100644
> --- a/block/blk-iocost.c
> +++ b/block/blk-iocost.c
[ ... ]
> @@ -3003,7 +3003,7 @@ static void ioc_pd_init(struct blkg_policy_data *pd)
> init_waitqueue_head(&iocg->waitq);
> hrtimer_setup(&iocg->waitq_timer, iocg_waitq_timer_fn, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
>
> - iocg->level = blkg->blkcg->css.cgroup->level;
> + iocg->level = cgroup_level(blkg->blkcg->css.cgroup)
^
Is this missing a semicolon? The line should end with a semicolon to
make this valid C syntax. This will prevent the kernel from building
in the ioc_pd_init() function.
>
> for (tblkg = blkg; tblkg; tblkg = tblkg->parent) {
> struct ioc_gq *tiocg = blkg_to_iocg(tblkg);
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/20310204023
© 2016 - 2026 Red Hat, Inc.