bpf: Add bpf_cgroup_from_id() kfunc

cgroup ID is an userspace-visible 64bit value uniquely identifying a given
cgroup. As the IDs are used widely, it's useful to be able to look up the
matching cgroups. Add bpf_cgroup_from_id().

v2: Separate out selftest into its own patch as suggested by Alexei.

Signed-off-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/r/Y/bBaG96t0/gQl9/@slm.duckdns.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Tejun Heo 2023-02-22 15:29:12 -10:00 committed by Alexei Starovoitov
parent 746ce76712
commit 332ea1f697
2 changed files with 25 additions and 3 deletions

View File

@ -583,13 +583,17 @@ Here's an example of how it can be used:
---- ----
Another kfunc available for interacting with ``struct cgroup *`` objects is Other kfuncs available for interacting with ``struct cgroup *`` objects are
bpf_cgroup_ancestor(). This allows callers to access the ancestor of a cgroup, bpf_cgroup_ancestor() and bpf_cgroup_from_id(), allowing callers to access
and return it as a cgroup kptr. the ancestor of a cgroup and find a cgroup by its ID, respectively. Both
return a cgroup kptr.
.. kernel-doc:: kernel/bpf/helpers.c .. kernel-doc:: kernel/bpf/helpers.c
:identifiers: bpf_cgroup_ancestor :identifiers: bpf_cgroup_ancestor
.. kernel-doc:: kernel/bpf/helpers.c
:identifiers: bpf_cgroup_from_id
Eventually, BPF should be updated to allow this to happen with a normal memory Eventually, BPF should be updated to allow this to happen with a normal memory
load in the program itself. This is currently not possible without more work in load in the program itself. This is currently not possible without more work in
the verifier. bpf_cgroup_ancestor() can be used as follows: the verifier. bpf_cgroup_ancestor() can be used as follows:

View File

@ -2101,6 +2101,23 @@ __bpf_kfunc struct cgroup *bpf_cgroup_ancestor(struct cgroup *cgrp, int level)
cgroup_get(ancestor); cgroup_get(ancestor);
return ancestor; return ancestor;
} }
/**
* bpf_cgroup_from_id - Find a cgroup from its ID. A cgroup returned by this
* kfunc which is not subsequently stored in a map, must be released by calling
* bpf_cgroup_release().
* @cgrp: The cgroup for which we're performing a lookup.
* @level: The level of ancestor to look up.
*/
__bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid)
{
struct cgroup *cgrp;
cgrp = cgroup_get_from_id(cgid);
if (IS_ERR(cgrp))
return NULL;
return cgrp;
}
#endif /* CONFIG_CGROUPS */ #endif /* CONFIG_CGROUPS */
/** /**
@ -2167,6 +2184,7 @@ BTF_ID_FLAGS(func, bpf_cgroup_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS)
BTF_ID_FLAGS(func, bpf_cgroup_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_cgroup_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL)
BTF_ID_FLAGS(func, bpf_cgroup_release, KF_RELEASE) BTF_ID_FLAGS(func, bpf_cgroup_release, KF_RELEASE)
BTF_ID_FLAGS(func, bpf_cgroup_ancestor, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_cgroup_ancestor, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL)
BTF_ID_FLAGS(func, bpf_cgroup_from_id, KF_ACQUIRE | KF_RET_NULL)
#endif #endif
BTF_ID_FLAGS(func, bpf_task_from_pid, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_task_from_pid, KF_ACQUIRE | KF_RET_NULL)
BTF_SET8_END(generic_btf_ids) BTF_SET8_END(generic_btf_ids)