| 1 | |
| 2 | |
| 3 |
|
| 4 | =========================================
|
| 5 | BPF_MAP_TYPE_QUEUE and BPF_MAP_TYPE_STACK
|
| 6 | =========================================
|
| 7 |
|
| 8 | .. note::
|
| 9 | - ``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` were introduced
|
| 10 | in kernel version 4.20
|
| 11 |
|
| 12 | ``BPF_MAP_TYPE_QUEUE`` provides FIFO storage and ``BPF_MAP_TYPE_STACK``
|
| 13 | provides LIFO storage for BPF programs. These maps support peek, pop and
|
| 14 | push operations that are exposed to BPF programs through the respective
|
| 15 | helpers. These operations are exposed to userspace applications using
|
| 16 | the existing ``bpf`` syscall in the following way:
|
| 17 |
|
| 18 | - ``BPF_MAP_LOOKUP_ELEM`` -> peek
|
| 19 | - ``BPF_MAP_LOOKUP_AND_DELETE_ELEM`` -> pop
|
| 20 | - ``BPF_MAP_UPDATE_ELEM`` -> push
|
| 21 |
|
| 22 | ``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` do not support
|
| 23 | ``BPF_F_NO_PREALLOC``.
|
| 24 |
|
| 25 | Usage
|
| 26 | =====
|
| 27 |
|
| 28 | Kernel BPF
|
| 29 | ----------
|
| 30 |
|
| 31 | bpf_map_push_elem()
|
| 32 | ~~~~~~~~~~~~~~~~~~~
|
| 33 |
|
| 34 | .. code-block:: c
|
| 35 |
|
| 36 | long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
|
| 37 |
|
| 38 | An element ``value`` can be added to a queue or stack using the
|
| 39 | ``bpf_map_push_elem`` helper. The ``flags`` parameter must be set to
|
| 40 | ``BPF_ANY`` or ``BPF_EXIST``. If ``flags`` is set to ``BPF_EXIST`` then,
|
| 41 | when the queue or stack is full, the oldest element will be removed to
|
| 42 | make room for ``value`` to be added. Returns ``0`` on success, or
|
| 43 | negative error in case of failure.
|
| 44 |
|
| 45 | bpf_map_peek_elem()
|
| 46 | ~~~~~~~~~~~~~~~~~~~
|
| 47 |
|
| 48 | .. code-block:: c
|
| 49 |
|
| 50 | long bpf_map_peek_elem(struct bpf_map *map, void *value)
|
| 51 |
|
| 52 | This helper fetches an element ``value`` from a queue or stack without
|
| 53 | removing it. Returns ``0`` on success, or negative error in case of
|
| 54 | failure.
|
| 55 |
|
| 56 | bpf_map_pop_elem()
|
| 57 | ~~~~~~~~~~~~~~~~~~
|
| 58 |
|
| 59 | .. code-block:: c
|
| 60 |
|
| 61 | long bpf_map_pop_elem(struct bpf_map *map, void *value)
|
| 62 |
|
| 63 | This helper removes an element into ``value`` from a queue or
|
| 64 | stack. Returns ``0`` on success, or negative error in case of failure.
|
| 65 |
|
| 66 |
|
| 67 | Userspace
|
| 68 | ---------
|
| 69 |
|
| 70 | bpf_map_update_elem()
|
| 71 | ~~~~~~~~~~~~~~~~~~~~~
|
| 72 |
|
| 73 | .. code-block:: c
|
| 74 |
|
| 75 | int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags)
|
| 76 |
|
| 77 | A userspace program can push ``value`` onto a queue or stack using libbpf's
|
| 78 | ``bpf_map_update_elem`` function. The ``key`` parameter must be set to
|
| 79 | ``NULL`` and ``flags`` must be set to ``BPF_ANY`` or ``BPF_EXIST``, with the
|
| 80 | same semantics as the ``bpf_map_push_elem`` kernel helper. Returns ``0`` on
|
| 81 | success, or negative error in case of failure.
|
| 82 |
|
| 83 | bpf_map_lookup_elem()
|
| 84 | ~~~~~~~~~~~~~~~~~~~~~
|
| 85 |
|
| 86 | .. code-block:: c
|
| 87 |
|
| 88 | int bpf_map_lookup_elem (int fd, const void *key, void *value)
|
| 89 |
|
| 90 | A userspace program can peek at the ``value`` at the head of a queue or stack
|
| 91 | using the libbpf ``bpf_map_lookup_elem`` function. The ``key`` parameter must be
|
| 92 | set to ``NULL``. Returns ``0`` on success, or negative error in case of
|
| 93 | failure.
|
| 94 |
|
| 95 | bpf_map_lookup_and_delete_elem()
|
| 96 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 97 |
|
| 98 | .. code-block:: c
|
| 99 |
|
| 100 | int bpf_map_lookup_and_delete_elem (int fd, const void *key, void *value)
|
| 101 |
|
| 102 | A userspace program can pop a ``value`` from the head of a queue or stack using
|
| 103 | the libbpf ``bpf_map_lookup_and_delete_elem`` function. The ``key`` parameter
|
| 104 | must be set to ``NULL``. Returns ``0`` on success, or negative error in case of
|
| 105 | failure.
|
| 106 |
|
| 107 | Examples
|
| 108 | ========
|
| 109 |
|
| 110 | Kernel BPF
|
| 111 | ----------
|
| 112 |
|
| 113 | This snippet shows how to declare a queue in a BPF program:
|
| 114 |
|
| 115 | .. code-block:: c
|
| 116 |
|
| 117 | struct {
|
| 118 | __uint(type, BPF_MAP_TYPE_QUEUE);
|
| 119 | __type(value, __u32);
|
| 120 | __uint(max_entries, 10);
|
| 121 | } queue SEC(".maps");
|
| 122 |
|
| 123 |
|
| 124 | Userspace
|
| 125 | ---------
|
| 126 |
|
| 127 | This snippet shows how to use libbpf's low-level API to create a queue from
|
| 128 | userspace:
|
| 129 |
|
| 130 | .. code-block:: c
|
| 131 |
|
| 132 | int create_queue()
|
| 133 | {
|
| 134 | return bpf_map_create(BPF_MAP_TYPE_QUEUE,
|
| 135 | "sample_queue", /* name */
|
| 136 | 0, /* key size, must be zero */
|
| 137 | sizeof(__u32), /* value size */
|
| 138 | 10, /* max entries */
|
| 139 | NULL); /* create options */
|
| 140 | }
|
| 141 |
|
| 142 |
|
| 143 | References
|
| 144 | ==========
|
| 145 |
|
| 146 | https://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/
|