162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci.. Copyright (C) 2022 Red Hat, Inc.
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci=========================================
562306a36Sopenharmony_ciBPF_MAP_TYPE_QUEUE and BPF_MAP_TYPE_STACK
662306a36Sopenharmony_ci=========================================
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci.. note::
962306a36Sopenharmony_ci   - ``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` were introduced
1062306a36Sopenharmony_ci     in kernel version 4.20
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci``BPF_MAP_TYPE_QUEUE`` provides FIFO storage and ``BPF_MAP_TYPE_STACK``
1362306a36Sopenharmony_ciprovides LIFO storage for BPF programs. These maps support peek, pop and
1462306a36Sopenharmony_cipush operations that are exposed to BPF programs through the respective
1562306a36Sopenharmony_cihelpers. These operations are exposed to userspace applications using
1662306a36Sopenharmony_cithe existing ``bpf`` syscall in the following way:
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci- ``BPF_MAP_LOOKUP_ELEM`` -> peek
1962306a36Sopenharmony_ci- ``BPF_MAP_LOOKUP_AND_DELETE_ELEM`` -> pop
2062306a36Sopenharmony_ci- ``BPF_MAP_UPDATE_ELEM`` -> push
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` do not support
2362306a36Sopenharmony_ci``BPF_F_NO_PREALLOC``.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciUsage
2662306a36Sopenharmony_ci=====
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciKernel BPF
2962306a36Sopenharmony_ci----------
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cibpf_map_push_elem()
3262306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci.. code-block:: c
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci   long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciAn element ``value`` can be added to a queue or stack using the
3962306a36Sopenharmony_ci``bpf_map_push_elem`` helper. The ``flags`` parameter must be set to
4062306a36Sopenharmony_ci``BPF_ANY`` or ``BPF_EXIST``. If ``flags`` is set to ``BPF_EXIST`` then,
4162306a36Sopenharmony_ciwhen the queue or stack is full, the oldest element will be removed to
4262306a36Sopenharmony_cimake room for ``value`` to be added. Returns ``0`` on success, or
4362306a36Sopenharmony_cinegative error in case of failure.
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cibpf_map_peek_elem()
4662306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci.. code-block:: c
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci   long bpf_map_peek_elem(struct bpf_map *map, void *value)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ciThis helper fetches an element ``value`` from a queue or stack without
5362306a36Sopenharmony_ciremoving it. Returns ``0`` on success, or negative error in case of
5462306a36Sopenharmony_cifailure.
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cibpf_map_pop_elem()
5762306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci.. code-block:: c
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci   long bpf_map_pop_elem(struct bpf_map *map, void *value)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciThis helper removes an element into ``value`` from a queue or
6462306a36Sopenharmony_cistack. Returns ``0`` on success, or negative error in case of failure.
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciUserspace
6862306a36Sopenharmony_ci---------
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cibpf_map_update_elem()
7162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci.. code-block:: c
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci   int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags)
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciA userspace program can push ``value`` onto a queue or stack using libbpf's
7862306a36Sopenharmony_ci``bpf_map_update_elem`` function. The ``key`` parameter must be set to
7962306a36Sopenharmony_ci``NULL`` and ``flags`` must be set to ``BPF_ANY`` or ``BPF_EXIST``, with the
8062306a36Sopenharmony_cisame semantics as the ``bpf_map_push_elem`` kernel helper. Returns ``0`` on
8162306a36Sopenharmony_cisuccess, or negative error in case of failure.
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cibpf_map_lookup_elem()
8462306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci.. code-block:: c
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci   int bpf_map_lookup_elem (int fd, const void *key, void *value)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciA userspace program can peek at the ``value`` at the head of a queue or stack
9162306a36Sopenharmony_ciusing the libbpf ``bpf_map_lookup_elem`` function. The ``key`` parameter must be
9262306a36Sopenharmony_ciset to ``NULL``.  Returns ``0`` on success, or negative error in case of
9362306a36Sopenharmony_cifailure.
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cibpf_map_lookup_and_delete_elem()
9662306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci.. code-block:: c
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci   int bpf_map_lookup_and_delete_elem (int fd, const void *key, void *value)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciA userspace program can pop a ``value`` from the head of a queue or stack using
10362306a36Sopenharmony_cithe libbpf ``bpf_map_lookup_and_delete_elem`` function. The ``key`` parameter
10462306a36Sopenharmony_cimust be set to ``NULL``. Returns ``0`` on success, or negative error in case of
10562306a36Sopenharmony_cifailure.
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciExamples
10862306a36Sopenharmony_ci========
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciKernel BPF
11162306a36Sopenharmony_ci----------
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciThis snippet shows how to declare a queue in a BPF program:
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci.. code-block:: c
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci    struct {
11862306a36Sopenharmony_ci            __uint(type, BPF_MAP_TYPE_QUEUE);
11962306a36Sopenharmony_ci            __type(value, __u32);
12062306a36Sopenharmony_ci            __uint(max_entries, 10);
12162306a36Sopenharmony_ci    } queue SEC(".maps");
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciUserspace
12562306a36Sopenharmony_ci---------
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciThis snippet shows how to use libbpf's low-level API to create a queue from
12862306a36Sopenharmony_ciuserspace:
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci.. code-block:: c
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci    int create_queue()
13362306a36Sopenharmony_ci    {
13462306a36Sopenharmony_ci            return bpf_map_create(BPF_MAP_TYPE_QUEUE,
13562306a36Sopenharmony_ci                                  "sample_queue", /* name */
13662306a36Sopenharmony_ci                                  0,              /* key size, must be zero */
13762306a36Sopenharmony_ci                                  sizeof(__u32),  /* value size */
13862306a36Sopenharmony_ci                                  10,             /* max entries */
13962306a36Sopenharmony_ci                                  NULL);          /* create options */
14062306a36Sopenharmony_ci    }
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciReferences
14462306a36Sopenharmony_ci==========
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cihttps://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/
147