From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
To: "Michal Koutný" <mkoutny@suse.com>
Cc: Tejun Heo <tj@kernel.org>, Johannes Weiner <hannes@cmpxchg.org>,
cgroups@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>,
linux-hardening@vger.kernel.org,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Chen Ridong <chenridong@huaweicloud.com>
Subject: Re: [RFC] cgroup: Avoid thousands of -Wflex-array-member-not-at-end warnings
Date: Mon, 1 Sep 2025 17:21:22 +0200 [thread overview]
Message-ID: <d0c49dc9-c810-47d2-a3ce-d74196a39235@embeddedor.com> (raw)
In-Reply-To: <wkkrw7rot7cunlojzyga5fgik7374xgj7aptr6afiljqesd6a7@rrmmuq3o4muy>
On 9/1/25 15:37, Michal Koutný wrote:
> On Sat, Aug 30, 2025 at 03:30:11PM +0200, "Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:
>> Based on the comments above, it seems that the original code was expecting
>> cgrp->ancestors[0] and cgrp_ancestor_storage to share the same addres in
>> memory.
>
> Fortunately, it doesn't matter what the address of cgrp_ancestor_storage
> is. The important effect is that cgroup_root::cgrp is followed by
> sufficient space to store a pointer (accessed via cgroup::ancestors[0]).
>
>> However when I take a look at the pahole output, I see that these two members
>> are actually misaligned by 56 bytes. See below:
>
> So the root cgroup's ancestry may be saved inside the padding instead of
> the dedicated storage. I don't think it causes immediate issues but it'd
> be better not to write to these bytes. (Note that the layout depends on
> kernel config.) Thanks for the report Gustavo!
>
>
>> So, one solution for this is to use the TRAILING_OVERLAP() helper and
>> move these members at the end of `struct cgroup_root`. With this the
>> misalignment disappears (together with the 14722 warnings :) ), and now
>> both cgrp->ancestors[0] and cgrp_ancestor_storage share the same address
>> in memory. See below:
>
> I didn't know TRAILING_OVERLAP() but it sounds like the tool for such
> situations.
I recently introduced it. :)
> Why do you move struct cgroup at the end of struct cgroup_root?
Because struct cgroup ends in a flexible-array member `ancestors`.
This triggers the -Wflex-array-member-not-at-end warns about. So,
while `ancestors` is indeed a flexible array, any instance of
cgroup embedded in another struct should be placed at the end.
However, if we change it to something like this (and of course
updating any related code, accordingly):
- struct cgroup *ancestors[];
+ struct cgroup **ancestors;
Then the flex in the middle issue goes away, and we can have
struct cgroup embedded in another struct anywhere.
The question is if this would be an acceptable solution?
I'd probably prefer this to remain a flexible-array member,
but I'd like to hear people's opinions and feedback. :)
>
> (Actually, as I look at the macro's implementation, it should be
> --- a/include/linux/stddef.h
> +++ b/include/linux/stddef.h
> @@ -110,7 +110,7 @@ enum {
> struct { \
> unsigned char __offset_to_##FAM[offsetof(TYPE, FAM)]; \
> MEMBERS \
> - }; \
> + } __packed; \
> }
>
> #endif
> in order to avoid similar issues, no?)
The way to do it is like this:
+ TRAILING_OVERLAP(struct cgroup, cgrp, ancestors,
+ /* must follow cgrp for cgrp->ancestors[0], see above */
+ struct cgroup *cgrp_ancestor_storage;
+ ) __packed;
and this get us to the following:
struct cgroup_root {
...
/* --- cacheline 65 boundary (4160 bytes) was 56 bytes ago --- */
union {
struct cgroup cgrp __attribute__((__aligned__(1))); /* 4216 8192 */
struct {
unsigned char __offset_to_ancestors[5784]; /* 4216 5784 */
/* --- cacheline 156 boundary (9984 bytes) was 16 bytes ago --- */
struct cgroup * cgrp_ancestor_storage; /* 10000 8 */
}; /* 4216 5792 */
} __attribute__((__aligned__(1))); /* 4216 8192 */
/* size: 12408, cachelines: 194, members: 10 */
/* forced alignments: 2 */
/* last cacheline: 56 bytes */
} __attribute__((__aligned__(8)));
Notice the change in alignment in struct cgroup_root from
4096 (page alignment) to 8 bytes alignment. In any case,
the size (still) increases from 6400 to 12408 bytes.
Thanks
-Gustavo
next prev parent reply other threads:[~2025-09-01 15:21 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-30 13:30 [RFC] cgroup: Avoid thousands of -Wflex-array-member-not-at-end warnings Gustavo A. R. Silva
2025-09-01 1:29 ` Chen Ridong
2025-09-01 7:44 ` Gustavo A. R. Silva
2025-09-01 13:37 ` Michal Koutný
2025-09-01 15:21 ` Gustavo A. R. Silva [this message]
2025-09-01 15:44 ` Gustavo A. R. Silva
2025-09-01 18:04 ` Michal Koutný
2025-09-01 17:58 ` Michal Koutný
2025-09-02 7:56 ` Gustavo A. R. Silva
2025-09-02 11:17 ` Michal Koutný
2025-09-02 12:37 ` Gustavo A. R. Silva
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d0c49dc9-c810-47d2-a3ce-d74196a39235@embeddedor.com \
--to=gustavo@embeddedor.com \
--cc=cgroups@vger.kernel.org \
--cc=chenridong@huaweicloud.com \
--cc=gustavoars@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkoutny@suse.com \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).