| .. 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 | |
| ---------- | |
| bpf_map_push_elem() | |
| ~~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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. The ``flags`` parameter must be set to | |
| ``BPF_ANY`` or ``BPF_EXIST``. 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. | |
| bpf_map_peek_elem() | |
| ~~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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. | |
| bpf_map_pop_elem() | |
| ~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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 | |
| --------- | |
| bpf_map_update_elem() | |
| ~~~~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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`` or ``BPF_EXIST``, with the | |
| same semantics as the ``bpf_map_push_elem`` kernel helper. Returns ``0`` on | |
| success, or negative error in case of failure. | |
| bpf_map_lookup_elem() | |
| ~~~~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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. | |
| bpf_map_lookup_and_delete_elem() | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| .. code-block:: c | |
| 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's low-level API to create a queue from | |
| userspace: | |
| .. 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 */ | |
| NULL); /* create options */ | |
| } | |
| References | |
| ========== | |
| https://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/ |