forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs/bpf: Add documentation for new cgroup local storage
Add some descriptions and examples for BPF_MAP_TYPE_CGRP_STORAGE. Also illustate the major difference between BPF_MAP_TYPE_CGRP_STORAGE and BPF_MAP_TYPE_CGROUP_STORAGE and recommend to use BPF_MAP_TYPE_CGRP_STORAGE instead of BPF_MAP_TYPE_CGROUP_STORAGE in the end. Acked-by: David Vernet <[email protected]> Signed-off-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
- Loading branch information
1 parent
0a1b69d
commit d431980
Showing
1 changed file
with
109 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
.. SPDX-License-Identifier: GPL-2.0-only | ||
.. Copyright (C) 2022 Meta Platforms, Inc. and affiliates. | ||
========================= | ||
BPF_MAP_TYPE_CGRP_STORAGE | ||
========================= | ||
|
||
The ``BPF_MAP_TYPE_CGRP_STORAGE`` map type represents a local fix-sized | ||
storage for cgroups. It is only available with ``CONFIG_CGROUPS``. | ||
The programs are made available by the same Kconfig. The | ||
data for a particular cgroup can be retrieved by looking up the map | ||
with that cgroup. | ||
|
||
This document describes the usage and semantics of the | ||
``BPF_MAP_TYPE_CGRP_STORAGE`` map type. | ||
|
||
Usage | ||
===== | ||
|
||
The map key must be ``sizeof(int)`` representing a cgroup fd. | ||
To access the storage in a program, use ``bpf_cgrp_storage_get``:: | ||
|
||
void *bpf_cgrp_storage_get(struct bpf_map *map, struct cgroup *cgroup, void *value, u64 flags) | ||
|
||
``flags`` could be 0 or ``BPF_LOCAL_STORAGE_GET_F_CREATE`` which indicates that | ||
a new local storage will be created if one does not exist. | ||
|
||
The local storage can be removed with ``bpf_cgrp_storage_delete``:: | ||
|
||
long bpf_cgrp_storage_delete(struct bpf_map *map, struct cgroup *cgroup) | ||
|
||
The map is available to all program types. | ||
|
||
Examples | ||
======== | ||
|
||
A BPF program example with BPF_MAP_TYPE_CGRP_STORAGE:: | ||
|
||
#include <vmlinux.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_CGRP_STORAGE); | ||
__uint(map_flags, BPF_F_NO_PREALLOC); | ||
__type(key, int); | ||
__type(value, long); | ||
} cgrp_storage SEC(".maps"); | ||
|
||
SEC("tp_btf/sys_enter") | ||
int BPF_PROG(on_enter, struct pt_regs *regs, long id) | ||
{ | ||
struct task_struct *task = bpf_get_current_task_btf(); | ||
long *ptr; | ||
|
||
ptr = bpf_cgrp_storage_get(&cgrp_storage, task->cgroups->dfl_cgrp, 0, | ||
BPF_LOCAL_STORAGE_GET_F_CREATE); | ||
if (ptr) | ||
__sync_fetch_and_add(ptr, 1); | ||
|
||
return 0; | ||
} | ||
|
||
Userspace accessing map declared above:: | ||
|
||
#include <linux/bpf.h> | ||
#include <linux/libbpf.h> | ||
|
||
__u32 map_lookup(struct bpf_map *map, int cgrp_fd) | ||
{ | ||
__u32 *value; | ||
value = bpf_map_lookup_elem(bpf_map__fd(map), &cgrp_fd); | ||
if (value) | ||
return *value; | ||
return 0; | ||
} | ||
|
||
Difference Between BPF_MAP_TYPE_CGRP_STORAGE and BPF_MAP_TYPE_CGROUP_STORAGE | ||
============================================================================ | ||
|
||
The old cgroup storage map ``BPF_MAP_TYPE_CGROUP_STORAGE`` has been marked as | ||
deprecated (renamed to ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``). The new | ||
``BPF_MAP_TYPE_CGRP_STORAGE`` map should be used instead. The following | ||
illusates the main difference between ``BPF_MAP_TYPE_CGRP_STORAGE`` and | ||
``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``. | ||
|
||
(1). ``BPF_MAP_TYPE_CGRP_STORAGE`` can be used by all program types while | ||
``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` is available only to cgroup program types | ||
like BPF_CGROUP_INET_INGRESS or BPF_CGROUP_SOCK_OPS, etc. | ||
|
||
(2). ``BPF_MAP_TYPE_CGRP_STORAGE`` supports local storage for more than one | ||
cgroup while ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` only supports one cgroup | ||
which is attached by a BPF program. | ||
|
||
(3). ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` allocates local storage at attach time so | ||
``bpf_get_local_storage()`` always returns non-NULL local storage. | ||
``BPF_MAP_TYPE_CGRP_STORAGE`` allocates local storage at runtime so | ||
it is possible that ``bpf_cgrp_storage_get()`` may return null local storage. | ||
To avoid such null local storage issue, user space can do | ||
``bpf_map_update_elem()`` to pre-allocate local storage before a BPF program | ||
is attached. | ||
|
||
(4). ``BPF_MAP_TYPE_CGRP_STORAGE`` supports deleting local storage by a BPF program | ||
while ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` only deletes storage during | ||
prog detach time. | ||
|
||
So overall, ``BPF_MAP_TYPE_CGRP_STORAGE`` supports all ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` | ||
functionality and beyond. It is recommended to use ``BPF_MAP_TYPE_CGRP_STORAGE`` | ||
instead of ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``. |