1 .. SPDX-License-Identifier: GPL-2.0-only 2 .. Copyright (C) 2022 Red Hat, Inc. 3 4 ============================================== 5 BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARR 6 ============================================== 7 8 .. note:: 9 - ``BPF_MAP_TYPE_ARRAY`` was introduced in 10 - ``BPF_MAP_TYPE_PERCPU_ARRAY`` was introdu 11 12 ``BPF_MAP_TYPE_ARRAY`` and ``BPF_MAP_TYPE_PERC 13 storage. The key type is an unsigned 32-bit in 14 of constant size. The size of the array is def 15 creation time. All array elements are pre-allo 16 created. ``BPF_MAP_TYPE_PERCPU_ARRAY`` uses a 17 CPU whereas ``BPF_MAP_TYPE_ARRAY`` uses the sa 18 stored can be of any size, however, all array 19 bytes. 20 21 Since kernel 5.5, memory mapping may be enable 22 setting the flag ``BPF_F_MMAPABLE``. The map d 23 starts on the first page. Sufficient page-size 24 memory are allocated to store all array values 25 which in some cases will result in over-alloca 26 using this is increased performance and ease o 27 would not be required to use helper functions 28 29 Usage 30 ===== 31 32 Kernel BPF 33 ---------- 34 35 bpf_map_lookup_elem() 36 ~~~~~~~~~~~~~~~~~~~~~ 37 38 .. code-block:: c 39 40 void *bpf_map_lookup_elem(struct bpf_map *m 41 42 Array elements can be retrieved using the ``bp 43 This helper returns a pointer into the array e 44 with userspace reading the value, the user mus 45 ``__sync_fetch_and_add()`` when updating the v 46 47 bpf_map_update_elem() 48 ~~~~~~~~~~~~~~~~~~~~~ 49 50 .. code-block:: c 51 52 long bpf_map_update_elem(struct bpf_map *ma 53 54 Array elements can be updated using the ``bpf_ 55 56 ``bpf_map_update_elem()`` returns 0 on success 57 failure. 58 59 Since the array is of constant size, ``bpf_map 60 To clear an array element, you may use ``bpf_m 61 zero value to that index. 62 63 Per CPU Array 64 ------------- 65 66 Values stored in ``BPF_MAP_TYPE_ARRAY`` can be 67 across different CPUs. To restrict storage to 68 ``BPF_MAP_TYPE_PERCPU_ARRAY``. 69 70 When using a ``BPF_MAP_TYPE_PERCPU_ARRAY`` the 71 ``bpf_map_lookup_elem()`` helpers automaticall 72 CPU. 73 74 bpf_map_lookup_percpu_elem() 75 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 76 77 .. code-block:: c 78 79 void *bpf_map_lookup_percpu_elem(struct bpf 80 81 The ``bpf_map_lookup_percpu_elem()`` helper ca 82 value for a specific CPU. Returns value on suc 83 found or ``cpu`` is invalid. 84 85 Concurrency 86 ----------- 87 88 Since kernel version 5.1, the BPF infrastructu 89 to synchronize access. 90 91 Userspace 92 --------- 93 94 Access from userspace uses libbpf APIs with th 95 the map identified by its ``fd``. 96 97 Examples 98 ======== 99 100 Please see the ``tools/testing/selftests/bpf`` 101 examples. The code samples below demonstrate A 102 103 Kernel BPF 104 ---------- 105 106 This snippet shows how to declare an array in 107 108 .. code-block:: c 109 110 struct { 111 __uint(type, BPF_MAP_TYPE_ARRAY); 112 __type(key, u32); 113 __type(value, long); 114 __uint(max_entries, 256); 115 } my_map SEC(".maps"); 116 117 118 This example BPF program shows how to access a 119 120 .. code-block:: c 121 122 int bpf_prog(struct __sk_buff *skb) 123 { 124 struct iphdr ip; 125 int index; 126 long *value; 127 128 if (bpf_skb_load_bytes(skb, ETH_HL 129 return 0; 130 131 index = ip.protocol; 132 value = bpf_map_lookup_elem(&my_ma 133 if (value) 134 __sync_fetch_and_add(value 135 136 return 0; 137 } 138 139 Userspace 140 --------- 141 142 BPF_MAP_TYPE_ARRAY 143 ~~~~~~~~~~~~~~~~~~ 144 145 This snippet shows how to create an array, usi 146 set flags. 147 148 .. code-block:: c 149 150 #include <bpf/libbpf.h> 151 #include <bpf/bpf.h> 152 153 int create_array() 154 { 155 int fd; 156 LIBBPF_OPTS(bpf_map_create_opts, o 157 158 fd = bpf_map_create(BPF_MAP_TYPE_A 159 "example_array 160 sizeof(__u32), 161 sizeof(long), 162 256, 163 &opts); 164 return fd; 165 } 166 167 This snippet shows how to initialize the eleme 168 169 .. code-block:: c 170 171 int initialize_array(int fd) 172 { 173 __u32 i; 174 long value; 175 int ret; 176 177 for (i = 0; i < 256; i++) { 178 value = i; 179 ret = bpf_map_update_elem( 180 if (ret < 0) 181 return ret; 182 } 183 184 return ret; 185 } 186 187 This snippet shows how to retrieve an element 188 189 .. code-block:: c 190 191 int lookup(int fd) 192 { 193 __u32 index = 42; 194 long value; 195 int ret; 196 197 ret = bpf_map_lookup_elem(fd, &ind 198 if (ret < 0) 199 return ret; 200 201 /* use value here */ 202 assert(value == 42); 203 204 return ret; 205 } 206 207 BPF_MAP_TYPE_PERCPU_ARRAY 208 ~~~~~~~~~~~~~~~~~~~~~~~~~ 209 210 This snippet shows how to initialize the eleme 211 212 .. code-block:: c 213 214 int initialize_array(int fd) 215 { 216 int ncpus = libbpf_num_possible_cp 217 long values[ncpus]; 218 __u32 i, j; 219 int ret; 220 221 for (i = 0; i < 256 ; i++) { 222 for (j = 0; j < ncpus; j++ 223 values[j] = i; 224 ret = bpf_map_update_elem( 225 if (ret < 0) 226 return ret; 227 } 228 229 return ret; 230 } 231 232 This snippet shows how to access the per CPU e 233 234 .. code-block:: c 235 236 int lookup(int fd) 237 { 238 int ncpus = libbpf_num_possible_cp 239 __u32 index = 42, j; 240 long values[ncpus]; 241 int ret; 242 243 ret = bpf_map_lookup_elem(fd, &ind 244 if (ret < 0) 245 return ret; 246 247 for (j = 0; j < ncpus; j++) { 248 /* Use per CPU value here 249 assert(values[j] == 42); 250 } 251 252 return ret; 253 } 254 255 Semantics 256 ========= 257 258 As shown in the example above, when accessing 259 in userspace, each value is an array with ``nc 260 261 When calling ``bpf_map_update_elem()`` the fla 262 for these maps.
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.