€•¢YŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ*/translations/zh_CN/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/zh_TW/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/it_IT/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ja_JP/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ko_KR/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/pt_BR/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/sp_SP/bpf/map_cgroup_storage”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ%SPDX-License-Identifier: GPL-2.0-only”h]”hŒ%SPDX-License-Identifier: GPL-2.0-only”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒD/var/lib/git/docbuild/linux/Documentation/bpf/map_cgroup_storage.rst”h´Kubh¶)”}”(hŒCopyright (C) 2020 Google LLC.”h]”hŒCopyright (C) 2020 Google LLC.”…””}”hhÈsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hµhhh²hh³hÇh´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒBPF_MAP_TYPE_CGROUP_STORAGE”h]”hŒBPF_MAP_TYPE_CGROUP_STORAGE”…””}”(hhÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhØh²hh³hÇh´KubhŒ paragraph”“”)”}”(hX$The ``BPF_MAP_TYPE_CGROUP_STORAGE`` map type represents a local fix-sized storage. It is only available with ``CONFIG_CGROUP_BPF``, and to programs that attach to cgroups; the programs are made available by the same Kconfig. The storage is identified by the cgroup the program is attached to.”h]”(hŒThe ”…””}”(hhíh²hh³Nh´NubhŒliteral”“”)”}”(hŒ``BPF_MAP_TYPE_CGROUP_STORAGE``”h]”hŒBPF_MAP_TYPE_CGROUP_STORAGE”…””}”(hh÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhhíubhŒJ map type represents a local fix-sized storage. It is only available with ”…””}”(hhíh²hh³Nh´Nubhö)”}”(hŒ``CONFIG_CGROUP_BPF``”h]”hŒCONFIG_CGROUP_BPF”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhhíubhŒ¢, and to programs that attach to cgroups; the programs are made available by the same Kconfig. The storage is identified by the cgroup the program is attached to.”…””}”(hhíh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KhhØh²hubhì)”}”(hŒúThe map provide a local storage at the cgroup that the BPF program is attached to. It provides a faster and simpler access than the general purpose hash table, which performs a hash table lookups, and requires user to track live cgroups on their own.”h]”hŒúThe map provide a local storage at the cgroup that the BPF program is attached to. It provides a faster and simpler access than the general purpose hash table, which performs a hash table lookups, and requires user to track live cgroups on their own.”…””}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K hhØh²hubhì)”}”(hŒÀThis document describes the usage and semantics of the ``BPF_MAP_TYPE_CGROUP_STORAGE`` map type. Some of its behaviors was changed in Linux 5.9 and this document will describe the differences.”h]”(hŒ7This document describes the usage and semantics of the ”…””}”(hj/h²hh³Nh´Nubhö)”}”(hŒ``BPF_MAP_TYPE_CGROUP_STORAGE``”h]”hŒBPF_MAP_TYPE_CGROUP_STORAGE”…””}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj/ubhŒj map type. Some of its behaviors was changed in Linux 5.9 and this document will describe the differences.”…””}”(hj/h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KhhØh²hubh×)”}”(hhh]”(hÜ)”}”(hŒUsage”h]”hŒUsage”…””}”(hjRh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjOh²hh³hÇh´Kubhì)”}”(hŒ€The map uses key of type of either ``__u64 cgroup_inode_id`` or ``struct bpf_cgroup_storage_key``, declared in ``linux/bpf.h``::”h]”(hŒ#The map uses key of type of either ”…””}”(hj`h²hh³Nh´Nubhö)”}”(hŒ``__u64 cgroup_inode_id``”h]”hŒ__u64 cgroup_inode_id”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj`ubhŒ or ”…””}”(hj`h²hh³Nh´Nubhö)”}”(hŒ!``struct bpf_cgroup_storage_key``”h]”hŒstruct bpf_cgroup_storage_key”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj`ubhŒ, declared in ”…””}”(hj`h²hh³Nh´Nubhö)”}”(hŒ``linux/bpf.h``”h]”hŒ linux/bpf.h”…””}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj`ubhŒ:”…””}”(hj`h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KhjOh²hubhŒ literal_block”“”)”}”(hŒ\struct bpf_cgroup_storage_key { __u64 cgroup_inode_id; __u32 attach_type; };”h]”hŒ\struct bpf_cgroup_storage_key { __u64 cgroup_inode_id; __u32 attach_type; };”…””}”hj¦sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´KhjOh²hubhì)”}”(hŒj``cgroup_inode_id`` is the inode id of the cgroup directory. ``attach_type`` is the program's attach type.”h]”(hö)”}”(hŒ``cgroup_inode_id``”h]”hŒcgroup_inode_id”…””}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj´ubhŒ* is the inode id of the cgroup directory. ”…””}”(hj´h²hh³Nh´Nubhö)”}”(hŒ``attach_type``”h]”hŒ attach_type”…””}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj´ubhŒ is the program’s attach type.”…””}”(hj´h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K!hjOh²hubhì)”}”(hXHLinux 5.9 added support for type ``__u64 cgroup_inode_id`` as the key type. When this key type is used, then all attach types of the particular cgroup and map will share the same storage. Otherwise, if the type is ``struct bpf_cgroup_storage_key``, then programs of different attach types be isolated and see different storages.”h]”(hŒ!Linux 5.9 added support for type ”…””}”(hjâh²hh³Nh´Nubhö)”}”(hŒ``__u64 cgroup_inode_id``”h]”hŒ__u64 cgroup_inode_id”…””}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjâubhŒœ as the key type. When this key type is used, then all attach types of the particular cgroup and map will share the same storage. Otherwise, if the type is ”…””}”(hjâh²hh³Nh´Nubhö)”}”(hŒ!``struct bpf_cgroup_storage_key``”h]”hŒstruct bpf_cgroup_storage_key”…””}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjâubhŒQ, then programs of different attach types be isolated and see different storages.”…””}”(hjâh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K$hjOh²hubhì)”}”(hŒCTo access the storage in a program, use ``bpf_get_local_storage``::”h]”(hŒ(To access the storage in a program, use ”…””}”(hjh²hh³Nh´Nubhö)”}”(hŒ``bpf_get_local_storage``”h]”hŒbpf_get_local_storage”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubhŒ:”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K*hjOh²hubj¥)”}”(hŒ1void *bpf_get_local_storage(void *map, u64 flags)”h]”hŒ1void *bpf_get_local_storage(void *map, u64 flags)”…””}”hj4sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´K,hjOh²hubhì)”}”(hŒ3``flags`` is reserved for future use and must be 0.”h]”(hö)”}”(hŒ ``flags``”h]”hŒflags”…””}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjBubhŒ* is reserved for future use and must be 0.”…””}”(hjBh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K.hjOh²hubhì)”}”(hXZThere is no implicit synchronization. Storages of ``BPF_MAP_TYPE_CGROUP_STORAGE`` can be accessed by multiple programs across different CPUs, and user should take care of synchronization by themselves. The bpf infrastructure provides ``struct bpf_spin_lock`` to synchronize the storage. See ``tools/testing/selftests/bpf/progs/test_spin_lock.c``.”h]”(hŒ2There is no implicit synchronization. Storages of ”…””}”(hj^h²hh³Nh´Nubhö)”}”(hŒ``BPF_MAP_TYPE_CGROUP_STORAGE``”h]”hŒBPF_MAP_TYPE_CGROUP_STORAGE”…””}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj^ubhŒ™ can be accessed by multiple programs across different CPUs, and user should take care of synchronization by themselves. The bpf infrastructure provides ”…””}”(hj^h²hh³Nh´Nubhö)”}”(hŒ``struct bpf_spin_lock``”h]”hŒstruct bpf_spin_lock”…””}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj^ubhŒ! to synchronize the storage. See ”…””}”(hj^h²hh³Nh´Nubhö)”}”(hŒ6``tools/testing/selftests/bpf/progs/test_spin_lock.c``”h]”hŒ2tools/testing/selftests/bpf/progs/test_spin_lock.c”…””}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj^ubhŒ.”…””}”(hj^h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K0hjOh²hubeh}”(h]”Œusage”ah ]”h"]”Œusage”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒExamples”h]”hŒExamples”…””}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjªh²hh³hÇh´K7ubhì)”}”(hŒ:Usage with key type as ``struct bpf_cgroup_storage_key``::”h]”(hŒUsage with key type as ”…””}”(hj»h²hh³Nh´Nubhö)”}”(hŒ!``struct bpf_cgroup_storage_key``”h]”hŒstruct bpf_cgroup_storage_key”…””}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj»ubhŒ:”…””}”(hj»h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K9hjªh²hubj¥)”}”(hXc#include struct { __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); __type(key, struct bpf_cgroup_storage_key); __type(value, __u32); } cgroup_storage SEC(".maps"); int program(struct __sk_buff *skb) { __u32 *ptr = bpf_get_local_storage(&cgroup_storage, 0); __sync_fetch_and_add(ptr, 1); return 0; }”h]”hXc#include struct { __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); __type(key, struct bpf_cgroup_storage_key); __type(value, __u32); } cgroup_storage SEC(".maps"); int program(struct __sk_buff *skb) { __u32 *ptr = bpf_get_local_storage(&cgroup_storage, 0); __sync_fetch_and_add(ptr, 1); return 0; }”…””}”hjÛsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´K;hjªh²hubhì)”}”(hŒ(Userspace accessing map declared above::”h]”hŒ'Userspace accessing map declared above:”…””}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KKhjªh²hubj¥)”}”(hX#include #include __u32 map_lookup(struct bpf_map *map, __u64 cgrp, enum bpf_attach_type type) { struct bpf_cgroup_storage_key = { .cgroup_inode_id = cgrp, .attach_type = type, }; __u32 value; bpf_map_lookup_elem(bpf_map__fd(map), &key, &value); // error checking omitted return value; }”h]”hX#include #include __u32 map_lookup(struct bpf_map *map, __u64 cgrp, enum bpf_attach_type type) { struct bpf_cgroup_storage_key = { .cgroup_inode_id = cgrp, .attach_type = type, }; __u32 value; bpf_map_lookup_elem(bpf_map__fd(map), &key, &value); // error checking omitted return value; }”…””}”hj÷sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´KMhjªh²hubhì)”}”(hŒAAlternatively, using just ``__u64 cgroup_inode_id`` as key type::”h]”(hŒAlternatively, using just ”…””}”(hjh²hh³Nh´Nubhö)”}”(hŒ``__u64 cgroup_inode_id``”h]”hŒ__u64 cgroup_inode_id”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubhŒ as key type:”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K\hjªh²hubj¥)”}”(hXK#include struct { __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); __type(key, __u64); __type(value, __u32); } cgroup_storage SEC(".maps"); int program(struct __sk_buff *skb) { __u32 *ptr = bpf_get_local_storage(&cgroup_storage, 0); __sync_fetch_and_add(ptr, 1); return 0; }”h]”hXK#include struct { __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); __type(key, __u64); __type(value, __u32); } cgroup_storage SEC(".maps"); int program(struct __sk_buff *skb) { __u32 *ptr = bpf_get_local_storage(&cgroup_storage, 0); __sync_fetch_and_add(ptr, 1); return 0; }”…””}”hj%sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´K^hjªh²hubhì)”}”(hŒAnd userspace::”h]”hŒAnd userspace:”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´Knhjªh²hubj¥)”}”(hX #include #include __u32 map_lookup(struct bpf_map *map, __u64 cgrp, enum bpf_attach_type type) { __u32 value; bpf_map_lookup_elem(bpf_map__fd(map), &cgrp, &value); // error checking omitted return value; }”h]”hX #include #include __u32 map_lookup(struct bpf_map *map, __u64 cgrp, enum bpf_attach_type type) { __u32 value; bpf_map_lookup_elem(bpf_map__fd(map), &cgrp, &value); // error checking omitted return value; }”…””}”hjAsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¤h³hÇh´Kphjªh²hubeh}”(h]”Œexamples”ah ]”h"]”Œexamples”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K7ubh×)”}”(hhh]”(hÜ)”}”(hŒ Semantics”h]”hŒ Semantics”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjWh²hh³hÇh´K|ubhì)”}”(hŒß``BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE`` is a variant of this map type. This per-CPU variant will have different memory regions for each CPU for each storage. The non-per-CPU will have the same memory region for each storage.”h]”(hö)”}”(hŒ&``BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE``”h]”hŒ"BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE”…””}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjhubhŒ¹ is a variant of this map type. This per-CPU variant will have different memory regions for each CPU for each storage. The non-per-CPU will have the same memory region for each storage.”…””}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K~hjWh²hubhì)”}”(hXMPrior to Linux 5.9, the lifetime of a storage is precisely per-attachment, and for a single ``CGROUP_STORAGE`` map, there can be at most one program loaded that uses the map. A program may be attached to multiple cgroups or have multiple attach types, and each attach creates a fresh zeroed storage. The storage is freed upon detach.”h]”(hŒ\Prior to Linux 5.9, the lifetime of a storage is precisely per-attachment, and for a single ”…””}”(hj„h²hh³Nh´Nubhö)”}”(hŒ``CGROUP_STORAGE``”h]”hŒCGROUP_STORAGE”…””}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj„ubhŒß map, there can be at most one program loaded that uses the map. A program may be attached to multiple cgroups or have multiple attach types, and each attach creates a fresh zeroed storage. The storage is freed upon detach.”…””}”(hj„h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K‚hjWh²hubhì)”}”(hXƒThere is a one-to-one association between the map of each type (per-CPU and non-per-CPU) and the BPF program during load verification time. As a result, each map can only be used by one BPF program and each BPF program can only use one storage map of each type. Because of map can only be used by one BPF program, sharing of this cgroup's storage with other BPF programs were impossible.”h]”hX…There is a one-to-one association between the map of each type (per-CPU and non-per-CPU) and the BPF program during load verification time. As a result, each map can only be used by one BPF program and each BPF program can only use one storage map of each type. Because of map can only be used by one BPF program, sharing of this cgroup’s storage with other BPF programs were impossible.”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KˆhjWh²hubhì)”}”(hX\Since Linux 5.9, storage can be shared by multiple programs. When a program is attached to a cgroup, the kernel would create a new storage only if the map does not already contain an entry for the cgroup and attach type pair, or else the old storage is reused for the new attachment. If the map is attach type shared, then attach type is simply ignored during comparison. Storage is freed only when either the map or the cgroup attached to is being freed. Detaching will not directly free the storage, but it may cause the reference to the map to reach zero and indirectly freeing all storage in the map.”h]”hX\Since Linux 5.9, storage can be shared by multiple programs. When a program is attached to a cgroup, the kernel would create a new storage only if the map does not already contain an entry for the cgroup and attach type pair, or else the old storage is reused for the new attachment. If the map is attach type shared, then attach type is simply ignored during comparison. Storage is freed only when either the map or the cgroup attached to is being freed. Detaching will not directly free the storage, but it may cause the reference to the map to reach zero and indirectly freeing all storage in the map.”…””}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KhjWh²hubhì)”}”(hX4The map is not associated with any BPF program, thus making sharing possible. However, the BPF program can still only associate with one map of each type (per-CPU and non-per-CPU). A BPF program cannot use more than one ``BPF_MAP_TYPE_CGROUP_STORAGE`` or more than one ``BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE``.”h]”(hŒÜThe map is not associated with any BPF program, thus making sharing possible. However, the BPF program can still only associate with one map of each type (per-CPU and non-per-CPU). A BPF program cannot use more than one ”…””}”(hjÀh²hh³Nh´Nubhö)”}”(hŒ``BPF_MAP_TYPE_CGROUP_STORAGE``”h]”hŒBPF_MAP_TYPE_CGROUP_STORAGE”…””}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÀubhŒ or more than one ”…””}”(hjÀh²hh³Nh´Nubhö)”}”(hŒ&``BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE``”h]”hŒ"BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE”…””}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÀubhŒ.”…””}”(hjÀh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K˜hjWh²hubhì)”}”(hX€In all versions, userspace may use the attach parameters of cgroup and attach type pair in ``struct bpf_cgroup_storage_key`` as the key to the BPF map APIs to read or update the storage for a given attachment. For Linux 5.9 attach type shared storages, only the first value in the struct, cgroup inode id, is used during comparison, so userspace may just specify a ``__u64`` directly.”h]”(hŒ[In all versions, userspace may use the attach parameters of cgroup and attach type pair in ”…””}”(hjòh²hh³Nh´Nubhö)”}”(hŒ!``struct bpf_cgroup_storage_key``”h]”hŒstruct bpf_cgroup_storage_key”…””}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjòubhŒñ as the key to the BPF map APIs to read or update the storage for a given attachment. For Linux 5.9 attach type shared storages, only the first value in the struct, cgroup inode id, is used during comparison, so userspace may just specify a ”…””}”(hjòh²hh³Nh´Nubhö)”}”(hŒ ``__u64``”h]”hŒ__u64”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjòubhŒ directly.”…””}”(hjòh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´KžhjWh²hubhì)”}”(hŒŽThe storage is bound at attach time. Even if the program is attached to parent and triggers in child, the storage still belongs to the parent.”h]”hŒŽThe storage is bound at attach time. Even if the program is attached to parent and triggers in child, the storage still belongs to the parent.”…””}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K¥hjWh²hubhì)”}”(hŒ}Userspace cannot create a new entry in the map or delete an existing entry. Program test runs always use a temporary storage.”h]”hŒ}Userspace cannot create a new entry in the map or delete an existing entry. Program test runs always use a temporary storage.”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÇh´K¨hjWh²hubeh}”(h]”Œ semantics”ah ]”h"]”Œ semantics”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K|ubeh}”(h]”Œbpf-map-type-cgroup-storage”ah ]”h"]”Œbpf_map_type_cgroup_storage”ah$]”h&]”uh1hÖhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÛNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jsŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jMjJj§j¤jTjQjEjBuŒ nametypes”}”(jM‰j§‰jT‰jE‰uh}”(jJhØj¤jOjQjªjBjWuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.