1 .. SPDX-License-Identifier: GPL-2.0-only
2 .. Copyright (C) 2022 Red Hat, Inc.
4 ================================================
5 BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARRAY
6 ================================================
9 - ``BPF_MAP_TYPE_ARRAY`` was introduced in kernel version 3.19
10 - ``BPF_MAP_TYPE_PERCPU_ARRAY`` was introduced in version 4.6
12 ``BPF_MAP_TYPE_ARRAY`` and ``BPF_MAP_TYPE_PERCPU_ARRAY`` provide generic array
13 storage. The key type is an unsigned 32-bit integer (4 bytes) and the map is
14 of constant size. The size of the array is defined in ``max_entries`` at
15 creation time. All array elements are pre-allocated and zero initialized when
16 created. ``BPF_MAP_TYPE_PERCPU_ARRAY`` uses a different memory region for each
17 CPU whereas ``BPF_MAP_TYPE_ARRAY`` uses the same memory region. The value
18 stored can be of any size, however, all array elements are aligned to 8
21 Since kernel 5.5, memory mapping may be enabled for ``BPF_MAP_TYPE_ARRAY`` by
22 setting the flag ``BPF_F_MMAPABLE``. The map definition is page-aligned and
23 starts on the first page. Sufficient page-sized and page-aligned blocks of
24 memory are allocated to store all array values, starting on the second page,
25 which in some cases will result in over-allocation of memory. The benefit of
26 using this is increased performance and ease of use since userspace programs
27 would not be required to use helper functions to access and mutate data.
40 void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
42 Array elements can be retrieved using the ``bpf_map_lookup_elem()`` helper.
43 This helper returns a pointer into the array element, so to avoid data races
44 with userspace reading the value, the user must use primitives like
45 ``__sync_fetch_and_add()`` when updating the value in-place.
52 long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
54 Array elements can be updated using the ``bpf_map_update_elem()`` helper.
56 ``bpf_map_update_elem()`` returns 0 on success, or negative error in case of
59 Since the array is of constant size, ``bpf_map_delete_elem()`` is not supported.
60 To clear an array element, you may use ``bpf_map_update_elem()`` to insert a
61 zero value to that index.
66 Values stored in ``BPF_MAP_TYPE_ARRAY`` can be accessed by multiple programs
67 across different CPUs. To restrict storage to a single CPU, you may use a
68 ``BPF_MAP_TYPE_PERCPU_ARRAY``.
70 When using a ``BPF_MAP_TYPE_PERCPU_ARRAY`` the ``bpf_map_update_elem()`` and
71 ``bpf_map_lookup_elem()`` helpers automatically access the slot for the current
74 bpf_map_lookup_percpu_elem()
75 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79 void *bpf_map_lookup_percpu_elem(struct bpf_map *map, const void *key, u32 cpu)
81 The ``bpf_map_lookup_percpu_elem()`` helper can be used to lookup the array
82 value for a specific CPU. Returns value on success , or ``NULL`` if no entry was
83 found or ``cpu`` is invalid.
88 Since kernel version 5.1, the BPF infrastructure provides ``struct bpf_spin_lock``
89 to synchronize access.
94 Access from userspace uses libbpf APIs with the same names as above, with
95 the map identified by its ``fd``.
100 Please see the ``tools/testing/selftests/bpf`` directory for functional
101 examples. The code samples below demonstrate API usage.
106 This snippet shows how to declare an array in a BPF program.
111 __uint(type, BPF_MAP_TYPE_ARRAY);
114 __uint(max_entries, 256);
115 } my_map SEC(".maps");
118 This example BPF program shows how to access an array element.
122 int bpf_prog(struct __sk_buff *skb)
128 if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip, sizeof(ip)) < 0)
132 value = bpf_map_lookup_elem(&my_map, &index);
134 __sync_fetch_and_add(value, skb->len);
145 This snippet shows how to create an array, using ``bpf_map_create_opts`` to
150 #include <bpf/libbpf.h>
156 LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
158 fd = bpf_map_create(BPF_MAP_TYPE_ARRAY,
159 "example_array", /* name */
160 sizeof(__u32), /* key size */
161 sizeof(long), /* value size */
162 256, /* max entries */
163 &opts); /* create opts */
167 This snippet shows how to initialize the elements of an array.
171 int initialize_array(int fd)
177 for (i = 0; i < 256; i++) {
179 ret = bpf_map_update_elem(fd, &i, &value, BPF_ANY);
187 This snippet shows how to retrieve an element value from an array.
197 ret = bpf_map_lookup_elem(fd, &index, &value);
207 BPF_MAP_TYPE_PERCPU_ARRAY
208 ~~~~~~~~~~~~~~~~~~~~~~~~~
210 This snippet shows how to initialize the elements of a per CPU array.
214 int initialize_array(int fd)
216 int ncpus = libbpf_num_possible_cpus();
221 for (i = 0; i < 256 ; i++) {
222 for (j = 0; j < ncpus; j++)
224 ret = bpf_map_update_elem(fd, &i, &values, BPF_ANY);
232 This snippet shows how to access the per CPU elements of an array value.
238 int ncpus = libbpf_num_possible_cpus();
243 ret = bpf_map_lookup_elem(fd, &index, &values);
247 for (j = 0; j < ncpus; j++) {
248 /* Use per CPU value here */
249 assert(values[j] == 42);
258 As shown in the example above, when accessing a ``BPF_MAP_TYPE_PERCPU_ARRAY``
259 in userspace, each value is an array with ``ncpus`` elements.
261 When calling ``bpf_map_update_elem()`` the flag ``BPF_NOEXIST`` can not be used