On 10/4/22 23:19, Donald Hunter wrote: > +Examples > +======== > + > +Please see the ``tools/testing/selftests/bpf`` directory for functional > +examples. The sample code below demonstrates API usage. > + Since you have many code snippets, better say "The code samples below". > +Kernel > +------ > + > +This snippet shows how to declare an array in a BPF program. > + > +.. code-block:: c > + > + struct { > + __uint(type, BPF_MAP_TYPE_ARRAY); > + __type(key, u32); > + __type(value, long); > + __uint(max_entries, 256); > + } my_map SEC(".maps"); > + > + > +This example shows how to access an array element. > + > +.. code-block:: c > + > + int bpf_prog(struct __sk_buff *skb) > + { > + int index = load_byte(skb, > + ETH_HLEN + offsetof(struct iphdr, protocol)); > + long *value; > + > + if (skb->pkt_type != PACKET_OUTGOING) > + return 0; > + > + value = bpf_map_lookup_elem(&my_map, &index); > + if (value) > + __sync_fetch_and_add(value, skb->len); > + > + return 0; > + } > + > +Userspace > +--------- > + > +BPF_MAP_TYPE_ARRAY > +~~~~~~~~~~~~~~~~~~ > + > +This example shows array creation, initialisation and lookup from userspace. > + "Initialize the array, set elements, and perform lookup". > +.. code-block:: c > + > + #include <assert.h> > + #include <bpf/libbpf.h> > + #include <bpf/bpf.h> > + > + int main(int argc, char **argv) > + { > + int fd; > + int ret = 0; > + long value; > + __u32 index = 42; > + __u32 i; > + > + fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "example_array", > + sizeof(__u32), sizeof(long), > + 256, 0); > + if (fd < 0) > + return fd; > + > + /* fill the map with values from 0-255 */ > + for (i = 0; i < 256 ; i++) { > + value = i; > + ret = bpf_map_update_elem(fd, &i, &value, BPF_ANY); > + if (ret < 0) > + return ret; > + } > + > + ret = bpf_map_lookup_elem(fd, &index, &value); > + if (ret < 0) > + return ret; > + > + assert(value == 42); > + > + return ret; > + } > + > +BPF_MAP_TYPE_PERCPU_ARRAY > +~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +This example shows per CPU array usage. > + > +.. code-block:: c > + > + #include <assert.h> > + #include <bpf/libbpf.h> > + #include <bpf/bpf.h> > + > + int main(int argc, char **argv) > + { > + int ncpus = libbpf_num_possible_cpus(); > + if (ncpus < 0) > + return ncpus; > + > + int fd; > + int ret = 0; > + __u32 i, j; > + __u32 index = 42; > + long v[ncpus], value[ncpus]; > + > + fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, "example_percpu", > + sizeof(__u32), sizeof(long), 256, 0); > + if (fd < 0) > + return -1; > + > + /* fill the map with values from 0-255 for each cpu */ > + for (i = 0; i < 256 ; i++) { > + for (j = 0; j < ncpus; j++) > + v[j] = i; > + ret = bpf_map_update_elem(fd, &i, &v, BPF_ANY); > + if (ret < 0) > + return ret; > + } > + > + ret = bpf_map_lookup_elem(fd, &index, &value); > + if (ret < 0) > + return ret; > + > + for (j = 0; j < ncpus; j++) > + assert(value[j] == 42); > + > + return ret; > + } > + What is the purpose of above snippet? Give more detailed explanation. Thanks. -- An old man doll... just what I always wanted! - Clara