Re: [PATCH v1 01/14] mm: introduce bpf struct ops for OOM handling
From: Martin KaFai Lau
Date: Mon Oct 06 2025 - 22:25:58 EST
On 10/3/25 7:00 PM, Roman Gushchin wrote:
Martin KaFai Lau <martin.lau@xxxxxxxxx> writes:
On 9/2/25 10:31 AM, Roman Gushchin wrote:
Btw, what's the right way to attach struct ops to a cgroup, if there is
one? Add a cgroup_id field to the struct and use it in the .reg()
Adding a cgroup id/fd field to the struct bpf_oom_ops will be hard to
attach the same bpf_oom_ops to multiple cgroups.
callback? Or there is something better?
There is a link_create.target_fd in the "union bpf_attr". The
cgroup_bpf_link_attach() is using it as cgroup fd. May be it can be
used here also. This will limit it to link attach only. Meaning the
SEC(".struct_ops.link") is supported but not the older
SEC(".struct_ops"). I think this should be fine.
I thought a bit more about it (sorry for the delay):
if we want to be able to attach a single struct ops to multiple cgroups
(and potentially other objects, e.g. sockets), we can't really
use the existing struct ops's bpf_link.
The existing 'struct bpf_struct_ops_link'? yeah, I think it needs to be extended.
So I guess we need to add a new .attach() function beside .reg()
which will take the existing link and struct bpf_attr as arguments and
return a new bpf_link. And in libbpf we need a corresponding new
bpf_link__attach_cgroup().
The target_fd (or cgroup_fd) is in attr. I think it is why the bpf_attr is needed during link_create (which calls .reg).
Other than link_create, the link_detach and link_update also need to know the cgroup but the cgroup_fd will not be in the attr. Only link_fd is available.
The cgroup probably needs to be stored in the link. The struct_ops has its 'struct bpf_struct_ops_link'. Potentially a future struct_ops can be attached to non-cgroup also (e.g. attach to a netns), so maybe adding a 'void *target;' to the 'struct bpf_struct_ops_link' and pass the attr to .reg(). Note that the link pointer has already passed to .reg(). Then the subsystem (oom handling here) can initialize the 'void *target;'.