On Fri, Nov 4, 2022 at 10:21 AM Donald Hunter <donald.hunter@xxxxxxxxx> wrote: > > Add documentation for BPF_MAP_TYPE_QUEUE and BPF_MAP_TYPE_STACK, > including usage and examples. > > Signed-off-by: Donald Hunter <donald.hunter@xxxxxxxxx> > --- > Documentation/bpf/map_queue_stack.rst | 119 ++++++++++++++++++++++++++ > 1 file changed, 119 insertions(+) > create mode 100644 Documentation/bpf/map_queue_stack.rst > > diff --git a/Documentation/bpf/map_queue_stack.rst b/Documentation/bpf/map_queue_stack.rst > new file mode 100644 > index 000000000000..a27e7f573869 > --- /dev/null > +++ b/Documentation/bpf/map_queue_stack.rst > @@ -0,0 +1,119 @@ > +.. SPDX-License-Identifier: GPL-2.0-only > +.. Copyright (C) 2022 Red Hat, Inc. > + > +========================================= > +BPF_MAP_TYPE_QUEUE and BPF_MAP_TYPE_STACK > +========================================= > + > +.. note:: > + - ``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` were introduced > + in kernel version 4.20 > + > +``BPF_MAP_TYPE_QUEUE`` provides FIFO storage and ``BPF_MAP_TYPE_STACK`` > +provides LIFO storage for BPF programs. These maps support peek, pop and > +push operations that are exposed to BPF programs through the respective > +helpers. These operations are exposed to userspace applications using > +the existing ``bpf`` syscall in the following way: > + > +- ``BPF_MAP_LOOKUP_ELEM`` -> peek > +- ``BPF_MAP_LOOKUP_AND_DELETE_ELEM`` -> pop > +- ``BPF_MAP_UPDATE_ELEM`` -> push > + > +``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` do not support > +``BPF_F_NO_PREALLOC``. > + > +Usage > +===== > + > +Kernel BPF > +---------- > + > +.. c:function:: > + long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags) > + > +An element ``value`` can be added to a queue or stack using the > +``bpf_map_push_elem()`` helper. If ``flags`` is set to ``BPF_EXIST`` > +then, when the queue or stack is full, the oldest element will be > +removed to make room for ``value`` to be added. Returns ``0`` on > +success, or negative error in case of failure. > + > +.. c:function:: > + long bpf_map_peek_elem(struct bpf_map *map, void *value) > + > +This helper fetches an element ``value`` from a queue or stack without > +removing it. Returns ``0`` on success, or negative error in case of > +failure. > + > +.. c:function:: > + long bpf_map_pop_elem(struct bpf_map *map, void *value) > + > +This helper removes an element into ``value`` from a queue or > +stack. Returns ``0`` on success, or negative error in case of failure. > + > + > +Userspace > +--------- > + > +.. c:function:: > + int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags) > + > +A userspace program can push ``value`` onto a queue or stack using libbpf's > +``bpf_map_update_elem`` function. The ``key`` parameter must be set to > +``NULL`` and ``flags`` must be set to ``BPF_ANY``. Returns ``0`` on > +success, or negative error in case of failure. > + > +.. c:function:: > + int bpf_map_lookup_elem (int fd, const void *key, void *value) > + > +A userspace program can peek at the ``value`` at the head of a queue or stack > +using the libbpf ``bpf_map_lookup_elem`` function. The ``key`` parameter must be > +set to ``NULL``. Returns ``0`` on success, or negative error in case of > +failure. > + > +.. c:function:: > + int bpf_map_lookup_and_delete_elem (int fd, const void *key, void *value) > + > +A userspace program can pop a ``value`` from the head of a queue or stack using > +the libbpf ``bpf_map_lookup_and_delete_elem`` function. The ``key`` parameter > +must be set to ``NULL``. Returns ``0`` on success, or negative error in case of > +failure. > + > +Examples > +======== > + > +Kernel BPF > +---------- > + > +This snippet shows how to declare a queue in a BPF program: > + > +.. code-block:: c > + > + struct { > + __uint(type, BPF_MAP_TYPE_QUEUE); > + __type(value, __u32); > + __uint(max_entries, 10); > + } queue SEC(".maps"); > + > + > +Userspace > +--------- > + > +This snippet shows how to use libbpf to create a queue from userspace: I'd prefer "how to use libbpf's low-level API to create a queue". Because ideally people use the declarative way shown above, which is also "use libbpf to create", but is simpler and preserves all the BTF type information (if map supports it). > + > +.. code-block:: c > + > + int create_queue() > + { > + return bpf_map_create(BPF_MAP_TYPE_QUEUE, > + "sample_queue", /* name */ > + 0, /* key size, must be zero */ > + sizeof(__u32), /* value size */ > + 10, /* max entries */ > + 0); /* create options */ NULL, it's a pointer > + } > + > + > +References > +========== > + > +https://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/ > -- > 2.35.1 >