{ssphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget!/translations/zh_CN/bpf/map_arraymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/zh_TW/bpf/map_arraymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/it_IT/bpf/map_arraymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/ja_JP/bpf/map_arraymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/ko_KR/bpf/map_arraymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/sp_SP/bpf/map_arraymodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h%SPDX-License-Identifier: GPL-2.0-onlyh]h%SPDX-License-Identifier: GPL-2.0-only}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh;/var/lib/git/docbuild/linux/Documentation/bpf/map_array.rsthKubh)}(h Copyright (C) 2022 Red Hat, Inc.h]h Copyright (C) 2022 Red Hat, Inc.}hhsbah}(h]h ]h"]h$]h&]hhuh1hhhhhhhhKubhsection)}(hhh](htitle)}(h0BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARRAYh]h0BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARRAY}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhnote)}(h|- ``BPF_MAP_TYPE_ARRAY`` was introduced in kernel version 3.19 - ``BPF_MAP_TYPE_PERCPU_ARRAY`` was introduced in version 4.6h]h bullet_list)}(hhh](h list_item)}(h<``BPF_MAP_TYPE_ARRAY`` was introduced in kernel version 3.19h]h paragraph)}(hhh](hliteral)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh& was introduced in kernel version 3.19}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhubh)}(h;``BPF_MAP_TYPE_PERCPU_ARRAY`` was introduced in version 4.6h]h)}(hjh](h)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh was introduced in version 4.6}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hj ubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhhhhNhNubh)}(hX``BPF_MAP_TYPE_ARRAY`` and ``BPF_MAP_TYPE_PERCPU_ARRAY`` provide generic array storage. The key type is an unsigned 32-bit integer (4 bytes) and the map is of constant size. The size of the array is defined in ``max_entries`` at creation time. All array elements are pre-allocated and zero initialized when created. ``BPF_MAP_TYPE_PERCPU_ARRAY`` uses a different memory region for each CPU whereas ``BPF_MAP_TYPE_ARRAY`` uses the same memory region. The value stored can be of any size for ``BPF_MAP_TYPE_ARRAY`` and not more than ``PCPU_MIN_UNIT_SIZE`` (32 kB) for ``BPF_MAP_TYPE_PERCPU_ARRAY``. All array elements are aligned to 8 bytes.h](h)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh and }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh provide generic array storage. The key type is an unsigned 32-bit integer (4 bytes) and the map is of constant size. The size of the array is defined in }(hj@hhhNhNubh)}(h``max_entries``h]h max_entries}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh[ at creation time. All array elements are pre-allocated and zero initialized when created. }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh5 uses a different memory region for each CPU whereas }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubhF uses the same memory region. The value stored can be of any size for }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh and not more than }(hj@hhhNhNubh)}(h``PCPU_MIN_UNIT_SIZE``h]hPCPU_MIN_UNIT_SIZE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh (32 kB) for }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh,. All array elements are aligned to 8 bytes.}(hj@hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hXSince kernel 5.5, memory mapping may be enabled for ``BPF_MAP_TYPE_ARRAY`` by setting the flag ``BPF_F_MMAPABLE``. The map definition is page-aligned and starts on the first page. Sufficient page-sized and page-aligned blocks of memory are allocated to store all array values, starting on the second page, which in some cases will result in over-allocation of memory. The benefit of using this is increased performance and ease of use since userspace programs would not be required to use helper functions to access and mutate data.h](h4Since kernel 5.5, memory mapping may be enabled for }(hjhhhNhNubh)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh by setting the flag }(hjhhhNhNubh)}(h``BPF_F_MMAPABLE``h]hBPF_F_MMAPABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhX. The map definition is page-aligned and starts on the first page. Sufficient page-sized and page-aligned blocks of memory are allocated to store all array values, starting on the second page, which in some cases will result in over-allocation of memory. The benefit of using this is increased performance and ease of use since userspace programs would not be required to use helper functions to access and mutate data.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hUsageh]hUsage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hhh](h)}(h Kernel BPFh]h Kernel BPF}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK"ubh)}(hhh](h)}(hbpf_map_lookup_elem()h]hbpf_map_lookup_elem()}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj.hhhhhK%ubh literal_block)}(h?void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)h]h?void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)}hjAsbah}(h]h ]h"]h$]h&]hhforcelanguagechighlight_args}uh1j?hhhK'hj.hhubh)}(hXArray elements can be retrieved using the ``bpf_map_lookup_elem()`` helper. This helper returns a pointer into the array element, so to avoid data races with userspace reading the value, the user must use primitives like ``__sync_fetch_and_add()`` when updating the value in-place.h](h*Array elements can be retrieved using the }(hjThhhNhNubh)}(h``bpf_map_lookup_elem()``h]hbpf_map_lookup_elem()}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjTubh helper. This helper returns a pointer into the array element, so to avoid data races with userspace reading the value, the user must use primitives like }(hjThhhNhNubh)}(h``__sync_fetch_and_add()``h]h__sync_fetch_and_add()}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjTubh" when updating the value in-place.}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK+hj.hhubeh}(h]bpf-map-lookup-elemah ]h"]bpf_map_lookup_elem()ah$]h&]uh1hhjhhhhhK%ubh)}(hhh](h)}(hbpf_map_update_elem()h]hbpf_map_update_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK1ubj@)}(h\long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)h]h\long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhK3hjhhubh)}(hIArray elements can be updated using the ``bpf_map_update_elem()`` helper.h](h(Array elements can be updated using the }(hjhhhNhNubh)}(h``bpf_map_update_elem()``h]hbpf_map_update_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh helper.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK7hjhhubh)}(hU``bpf_map_update_elem()`` returns 0 on success, or negative error in case of failure.h](h)}(h``bpf_map_update_elem()``h]hbpf_map_update_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh< returns 0 on success, or negative error in case of failure.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK9hjhhubh)}(hSince the array is of constant size, ``bpf_map_delete_elem()`` is not supported. To clear an array element, you may use ``bpf_map_update_elem()`` to insert a zero value to that index.h](h%Since the array is of constant size, }(hjhhhNhNubh)}(h``bpf_map_delete_elem()``h]hbpf_map_delete_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh: is not supported. To clear an array element, you may use }(hjhhhNhNubh)}(h``bpf_map_update_elem()``h]hbpf_map_update_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh& to insert a zero value to that index.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhNhNubh)}(h``BPF_MAP_TYPE_ARRAY``h]hBPF_MAP_TYPE_ARRAY}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj>ubhp can be accessed by multiple programs across different CPUs. To restrict storage to a single CPU, you may use a }(hj>hhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj>ubh.}(hj>hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKChj-hhubh)}(hWhen using a ``BPF_MAP_TYPE_PERCPU_ARRAY`` the ``bpf_map_update_elem()`` and ``bpf_map_lookup_elem()`` helpers automatically access the slot for the current CPU.h](h When using a }(hjphhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjpubh the }(hjphhhNhNubh)}(h``bpf_map_update_elem()``h]hbpf_map_update_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjpubh and }(hjphhhNhNubh)}(h``bpf_map_lookup_elem()``h]hbpf_map_lookup_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjpubh; helpers automatically access the slot for the current CPU.}(hjphhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKGhj-hhubh)}(hhh](h)}(hbpf_map_lookup_percpu_elem()h]hbpf_map_lookup_percpu_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKLubj@)}(hOvoid *bpf_map_lookup_percpu_elem(struct bpf_map *map, const void *key, u32 cpu)h]hOvoid *bpf_map_lookup_percpu_elem(struct bpf_map *map, const void *key, u32 cpu)}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKNhjhhubh)}(hThe ``bpf_map_lookup_percpu_elem()`` helper can be used to lookup the array value for a specific CPU. Returns value on success , or ``NULL`` if no entry was found or ``cpu`` is invalid.h](hThe }(hjhhhNhNubh)}(h ``bpf_map_lookup_percpu_elem()``h]hbpf_map_lookup_percpu_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh` helper can be used to lookup the array value for a specific CPU. Returns value on success , or }(hjhhhNhNubh)}(h``NULL``h]hNULL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh if no entry was found or }(hjhhhNhNubh)}(h``cpu``h]hcpu}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh is invalid.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKRhjhhubeh}(h]bpf-map-lookup-percpu-elemah ]h"]bpf_map_lookup_percpu_elem()ah$]h&]uh1hhj-hhhhhKLubeh}(h] per-cpu-arrayah ]h"] per cpu arrayah$]h&]uh1hhj hhhhhKAubh)}(hhh](h)}(h Concurrencyh]h Concurrency}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj(hhhhhKWubh)}(hiSince kernel version 5.1, the BPF infrastructure provides ``struct bpf_spin_lock`` to synchronize access.h](h:Since kernel version 5.1, the BPF infrastructure provides }(hj9hhhNhNubh)}(h``struct bpf_spin_lock``h]hstruct bpf_spin_lock}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9ubh to synchronize access.}(hj9hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKYhj(hhubeh}(h] concurrencyah ]h"] concurrencyah$]h&]uh1hhj hhhhhKWubh)}(hhh](h)}(h Userspaceh]h Userspace}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjahhhhhK]ubh)}(hkAccess from userspace uses libbpf APIs with the same names as above, with the map identified by its ``fd``.h](hdAccess from userspace uses libbpf APIs with the same names as above, with the map identified by its }(hjrhhhNhNubh)}(h``fd``h]hfd}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjrubh.}(hjrhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK_hjahhubeh}(h] userspaceah ]h"]h$] userspaceah&]uh1hhj hhhhhK]j,Kubeh}(h]usageah ]h"]usageah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hExamplesh]hExamples}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKcubh)}(hPlease see the ``tools/testing/selftests/bpf`` directory for functional examples. The code samples below demonstrate API usage.h](hPlease see the }(hjhhhNhNubh)}(h``tools/testing/selftests/bpf``h]htools/testing/selftests/bpf}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhQ directory for functional examples. The code samples below demonstrate API usage.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKehjhhubh)}(hhh](h)}(h Kernel BPFh]h Kernel BPF}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKiubh)}(hThis example BPF program shows how to access an array element.h]h>This example BPF program shows how to access an array element.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjhhubj@)}(hXxint bpf_prog(struct __sk_buff *skb) { struct iphdr ip; int index; long *value; if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip, sizeof(ip)) < 0) return 0; index = ip.protocol; value = bpf_map_lookup_elem(&my_map, &index); if (value) __sync_fetch_and_add(value, skb->len); return 0; }h]hXxint bpf_prog(struct __sk_buff *skb) { struct iphdr ip; int index; long *value; if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip, sizeof(ip)) < 0) return 0; index = ip.protocol; value = bpf_map_lookup_elem(&my_map, &index); if (value) __sync_fetch_and_add(value, skb->len); return 0; }}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKyhjhhubeh}(h]id1ah ]h"]h$]j*ah&]uh1hhjhhhhhKij,Kubh)}(hhh](h)}(h Userspaceh]h Userspace}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj%hhhhhKubh)}(hhh](h)}(hBPF_MAP_TYPE_ARRAYh]hBPF_MAP_TYPE_ARRAY}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6hhhhhKubh)}(hVThis snippet shows how to create an array, using ``bpf_map_create_opts`` to set flags.h](h1This snippet shows how to create an array, using }(hjGhhhNhNubh)}(h``bpf_map_create_opts``h]hbpf_map_create_opts}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGubh to set flags.}(hjGhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj6hhubj@)}(hX3#include #include int create_array() { int fd; LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE); fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "example_array", /* name */ sizeof(__u32), /* key size */ sizeof(long), /* value size */ 256, /* max entries */ &opts); /* create opts */ return fd; }h]hX3#include #include int create_array() { int fd; LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE); fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "example_array", /* name */ sizeof(__u32), /* key size */ sizeof(long), /* value size */ 256, /* max entries */ &opts); /* create opts */ return fd; }}hjgsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKhj6hhubh)}(h>This snippet shows how to initialize the elements of an array.h]h>This snippet shows how to initialize the elements of an array.}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj6hhubj@)}(hX:int initialize_array(int fd) { __u32 i; long value; int ret; for (i = 0; i < 256; i++) { value = i; ret = bpf_map_update_elem(fd, &i, &value, BPF_ANY); if (ret < 0) return ret; } return ret; }h]hX:int initialize_array(int fd) { __u32 i; long value; int ret; for (i = 0; i < 256; i++) { value = i; ret = bpf_map_update_elem(fd, &i, &value, BPF_ANY); if (ret < 0) return ret; } return ret; }}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKhj6hhubh)}(hBThis snippet shows how to retrieve an element value from an array.h]hBThis snippet shows how to retrieve an element value from an array.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj6hhubj@)}(hXint lookup(int fd) { __u32 index = 42; long value; int ret; ret = bpf_map_lookup_elem(fd, &index, &value); if (ret < 0) return ret; /* use value here */ assert(value == 42); return ret; }h]hXint lookup(int fd) { __u32 index = 42; long value; int ret; ret = bpf_map_lookup_elem(fd, &index, &value); if (ret < 0) return ret; /* use value here */ assert(value == 42); return ret; }}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKhj6hhubeh}(h]bpf-map-type-arrayah ]h"]bpf_map_type_arrayah$]h&]uh1hhj%hhhhhKubh)}(hhh](h)}(hBPF_MAP_TYPE_PERCPU_ARRAYh]hBPF_MAP_TYPE_PERCPU_ARRAY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hEThis snippet shows how to initialize the elements of a per CPU array.h]hEThis snippet shows how to initialize the elements of a per CPU array.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj@)}(hXint initialize_array(int fd) { int ncpus = libbpf_num_possible_cpus(); long values[ncpus]; __u32 i, j; int ret; for (i = 0; i < 256 ; i++) { for (j = 0; j < ncpus; j++) values[j] = i; ret = bpf_map_update_elem(fd, &i, &values, BPF_ANY); if (ret < 0) return ret; } return ret; }h]hXint initialize_array(int fd) { int ncpus = libbpf_num_possible_cpus(); long values[ncpus]; __u32 i, j; int ret; for (i = 0; i < 256 ; i++) { for (j = 0; j < ncpus; j++) values[j] = i; ret = bpf_map_update_elem(fd, &i, &values, BPF_ANY); if (ret < 0) return ret; } return ret; }}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKhjhhubh)}(hHThis snippet shows how to access the per CPU elements of an array value.h]hHThis snippet shows how to access the per CPU elements of an array value.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj@)}(hXint lookup(int fd) { int ncpus = libbpf_num_possible_cpus(); __u32 index = 42, j; long values[ncpus]; int ret; ret = bpf_map_lookup_elem(fd, &index, &values); if (ret < 0) return ret; for (j = 0; j < ncpus; j++) { /* Use per CPU value here */ assert(values[j] == 42); } return ret; }h]hXint lookup(int fd) { int ncpus = libbpf_num_possible_cpus(); __u32 index = 42, j; long values[ncpus]; int ret; ret = bpf_map_lookup_elem(fd, &index, &values); if (ret < 0) return ret; for (j = 0; j < ncpus; j++) { /* Use per CPU value here */ assert(values[j] == 42); } return ret; }}hjsbah}(h]h ]h"]h$]h&]hhjOjPjQjR}uh1j?hhhKhjhhubeh}(h]bpf-map-type-percpu-arrayah ]h"]bpf_map_type_percpu_arrayah$]h&]uh1hhj%hhhhhKubeh}(h]id2ah ]h"]h$]jah&]uh1hhjhhhhhKj,Kubeh}(h]examplesah ]h"]examplesah$]h&]uh1hhhhhhhhKcubh)}(hhh](h)}(h Semanticsh]h Semantics}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hAs shown in the example above, when accessing a ``BPF_MAP_TYPE_PERCPU_ARRAY`` in userspace, each value is an array with ``ncpus`` elements.h](h0As shown in the example above, when accessing a }(hj+hhhNhNubh)}(h``BPF_MAP_TYPE_PERCPU_ARRAY``h]hBPF_MAP_TYPE_PERCPU_ARRAY}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+ubh+ in userspace, each value is an array with }(hj+hhhNhNubh)}(h ``ncpus``h]hncpus}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+ubh elements.}(hj+hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h_When calling ``bpf_map_update_elem()`` the flag ``BPF_NOEXIST`` can not be used for these maps.h](h When calling }(hj]hhhNhNubh)}(h``bpf_map_update_elem()``h]hbpf_map_update_elem()}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhj]ubh the flag }(hj]hhhNhNubh)}(h``BPF_NOEXIST``h]h BPF_NOEXIST}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj]ubh can not be used for these maps.}(hj]hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h] semanticsah ]h"] semanticsah$]h&]uh1hhhhhhhhMubeh}(h]0bpf-map-type-array-and-bpf-map-type-percpu-arrayah ]h"]0bpf_map_type_array and bpf_map_type_percpu_arrayah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjj kernel bpfNjjj!jj%j"jjj^j[ userspaceNjjjjjjjju nametypes}(jjjjj!j%jj^jjjjjuh}(jhjj j&jjj.jjj"j-jjj[j(jjajjj jj j%jj6jjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages](hsystem_message)}(hhh]h)}(h-Duplicate implicit target name: "kernel bpf".h]h1Duplicate implicit target name: “kernel bpf”.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj(ubah}(h]h ]h"]h$]h&]j alevelKtypeINFOsourcehlineKiuh1j&hjhhhhhKiubj')}(hhh]h)}(h,Duplicate implicit target name: "userspace".h]h0Duplicate implicit target name: “userspace”.}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDubah}(h]h ]h"]h$]h&]j alevelKtypejAsourcehlineKuh1j&hj%hhhhhKubetransform_messages] transformerN include_log] decorationNhhub.