On Mon, Mar 18, 2024 at 10:04 PM Jose Fernandez josef@netflix.com wrote:
This patch enhances the BPF helpers by adding a kfunc to retrieve the cgroup v2 of a task, addressing a previous limitation where only bpf_task_get_cgroup1 was available for cgroup v1. The new kfunc is particularly useful for scenarios where obtaining the cgroup ID of a task other than the "current" one is necessary, which the existing bpf_get_current_cgroup_id helper cannot accommodate. A specific use case at Netflix involved the sched_switch tracepoint, where we had to get the cgroup IDs of both the prev and next tasks.
The bpf_task_get_cgroup kfunc acquires and returns a reference to a task's default cgroup, ensuring thread-safe access by correctly implementing RCU read locking and unlocking. It leverages the existing cgroup.h helper, and cgroup_tryget to safely acquire a reference to it.
Signed-off-by: Jose Fernandez josef@netflix.com Reviewed-by: Tycho Andersen tycho@tycho.pizza Acked-by: Yonghong Song yonghong.song@linux.dev Acked-by: Stanislav Fomichev sdf@google.com
V2 -> V3: No changes V1 -> V2: Return a pointer to the cgroup instead of the cgroup ID
kernel/bpf/helpers.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index a89587859571..bbd19d5eedb6 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -2266,6 +2266,31 @@ bpf_task_get_cgroup1(struct task_struct *task, int hierarchy_id) return NULL; return cgrp; }
+/**
- bpf_task_get_cgroup - Acquire a reference to the default cgroup of a task.
- @task: The target task
- This function returns the task's default cgroup, primarily
- designed for use with cgroup v2. In cgroup v1, the concept of default
- cgroup varies by subsystem, and while this function will work with
- cgroup v1, it's recommended to use bpf_task_get_cgroup1 instead.
- A cgroup returned by this kfunc which is not subsequently stored in a
- map, must be released by calling bpf_cgroup_release().
- Return: On success, the cgroup is returned. On failure, NULL is returned.
- */
+__bpf_kfunc struct cgroup *bpf_task_get_cgroup(struct task_struct *task) +{
struct cgroup *cgrp;
rcu_read_lock();
cgrp = task_dfl_cgroup(task);
if (!cgroup_tryget(cgrp))
cgrp = NULL;
rcu_read_unlock();
return cgrp;
+}
Tejun,
Does this patch look good to you?