164488ca5SDonald Hunter.. SPDX-License-Identifier: GPL-2.0-only 264488ca5SDonald Hunter.. Copyright (C) 2022 Red Hat, Inc. 364488ca5SDonald Hunter 464488ca5SDonald Hunter========================================= 564488ca5SDonald HunterBPF_MAP_TYPE_QUEUE and BPF_MAP_TYPE_STACK 664488ca5SDonald Hunter========================================= 764488ca5SDonald Hunter 864488ca5SDonald Hunter.. note:: 964488ca5SDonald Hunter - ``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` were introduced 1064488ca5SDonald Hunter in kernel version 4.20 1164488ca5SDonald Hunter 1264488ca5SDonald Hunter``BPF_MAP_TYPE_QUEUE`` provides FIFO storage and ``BPF_MAP_TYPE_STACK`` 1364488ca5SDonald Hunterprovides LIFO storage for BPF programs. These maps support peek, pop and 1464488ca5SDonald Hunterpush operations that are exposed to BPF programs through the respective 1564488ca5SDonald Hunterhelpers. These operations are exposed to userspace applications using 1664488ca5SDonald Hunterthe existing ``bpf`` syscall in the following way: 1764488ca5SDonald Hunter 1864488ca5SDonald Hunter- ``BPF_MAP_LOOKUP_ELEM`` -> peek 1964488ca5SDonald Hunter- ``BPF_MAP_LOOKUP_AND_DELETE_ELEM`` -> pop 2064488ca5SDonald Hunter- ``BPF_MAP_UPDATE_ELEM`` -> push 2164488ca5SDonald Hunter 2264488ca5SDonald Hunter``BPF_MAP_TYPE_QUEUE`` and ``BPF_MAP_TYPE_STACK`` do not support 2364488ca5SDonald Hunter``BPF_F_NO_PREALLOC``. 2464488ca5SDonald Hunter 2564488ca5SDonald HunterUsage 2664488ca5SDonald Hunter===== 2764488ca5SDonald Hunter 2864488ca5SDonald HunterKernel BPF 2964488ca5SDonald Hunter---------- 3064488ca5SDonald Hunter 31*539886a3SDonald Hunterbpf_map_push_elem() 32*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~~ 33*539886a3SDonald Hunter 34*539886a3SDonald Hunter.. code-block:: c 35*539886a3SDonald Hunter 3664488ca5SDonald Hunter long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags) 3764488ca5SDonald Hunter 3864488ca5SDonald HunterAn element ``value`` can be added to a queue or stack using the 3964488ca5SDonald Hunter``bpf_map_push_elem`` helper. The ``flags`` parameter must be set to 4064488ca5SDonald Hunter``BPF_ANY`` or ``BPF_EXIST``. If ``flags`` is set to ``BPF_EXIST`` then, 4164488ca5SDonald Hunterwhen the queue or stack is full, the oldest element will be removed to 4264488ca5SDonald Huntermake room for ``value`` to be added. Returns ``0`` on success, or 4364488ca5SDonald Hunternegative error in case of failure. 4464488ca5SDonald Hunter 45*539886a3SDonald Hunterbpf_map_peek_elem() 46*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~~ 47*539886a3SDonald Hunter 48*539886a3SDonald Hunter.. code-block:: c 49*539886a3SDonald Hunter 5064488ca5SDonald Hunter long bpf_map_peek_elem(struct bpf_map *map, void *value) 5164488ca5SDonald Hunter 5264488ca5SDonald HunterThis helper fetches an element ``value`` from a queue or stack without 5364488ca5SDonald Hunterremoving it. Returns ``0`` on success, or negative error in case of 5464488ca5SDonald Hunterfailure. 5564488ca5SDonald Hunter 56*539886a3SDonald Hunterbpf_map_pop_elem() 57*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~ 58*539886a3SDonald Hunter 59*539886a3SDonald Hunter.. code-block:: c 60*539886a3SDonald Hunter 6164488ca5SDonald Hunter long bpf_map_pop_elem(struct bpf_map *map, void *value) 6264488ca5SDonald Hunter 6364488ca5SDonald HunterThis helper removes an element into ``value`` from a queue or 6464488ca5SDonald Hunterstack. Returns ``0`` on success, or negative error in case of failure. 6564488ca5SDonald Hunter 6664488ca5SDonald Hunter 6764488ca5SDonald HunterUserspace 6864488ca5SDonald Hunter--------- 6964488ca5SDonald Hunter 70*539886a3SDonald Hunterbpf_map_update_elem() 71*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~~~~ 72*539886a3SDonald Hunter 73*539886a3SDonald Hunter.. code-block:: c 74*539886a3SDonald Hunter 7564488ca5SDonald Hunter int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags) 7664488ca5SDonald Hunter 7764488ca5SDonald HunterA userspace program can push ``value`` onto a queue or stack using libbpf's 7864488ca5SDonald Hunter``bpf_map_update_elem`` function. The ``key`` parameter must be set to 7964488ca5SDonald Hunter``NULL`` and ``flags`` must be set to ``BPF_ANY`` or ``BPF_EXIST``, with the 8064488ca5SDonald Huntersame semantics as the ``bpf_map_push_elem`` kernel helper. Returns ``0`` on 8164488ca5SDonald Huntersuccess, or negative error in case of failure. 8264488ca5SDonald Hunter 83*539886a3SDonald Hunterbpf_map_lookup_elem() 84*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~~~~ 85*539886a3SDonald Hunter 86*539886a3SDonald Hunter.. code-block:: c 87*539886a3SDonald Hunter 8864488ca5SDonald Hunter int bpf_map_lookup_elem (int fd, const void *key, void *value) 8964488ca5SDonald Hunter 9064488ca5SDonald HunterA userspace program can peek at the ``value`` at the head of a queue or stack 9164488ca5SDonald Hunterusing the libbpf ``bpf_map_lookup_elem`` function. The ``key`` parameter must be 9264488ca5SDonald Hunterset to ``NULL``. Returns ``0`` on success, or negative error in case of 9364488ca5SDonald Hunterfailure. 9464488ca5SDonald Hunter 95*539886a3SDonald Hunterbpf_map_lookup_and_delete_elem() 96*539886a3SDonald Hunter~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 97*539886a3SDonald Hunter 98*539886a3SDonald Hunter.. code-block:: c 99*539886a3SDonald Hunter 10064488ca5SDonald Hunter int bpf_map_lookup_and_delete_elem (int fd, const void *key, void *value) 10164488ca5SDonald Hunter 10264488ca5SDonald HunterA userspace program can pop a ``value`` from the head of a queue or stack using 10364488ca5SDonald Hunterthe libbpf ``bpf_map_lookup_and_delete_elem`` function. The ``key`` parameter 10464488ca5SDonald Huntermust be set to ``NULL``. Returns ``0`` on success, or negative error in case of 10564488ca5SDonald Hunterfailure. 10664488ca5SDonald Hunter 10764488ca5SDonald HunterExamples 10864488ca5SDonald Hunter======== 10964488ca5SDonald Hunter 11064488ca5SDonald HunterKernel BPF 11164488ca5SDonald Hunter---------- 11264488ca5SDonald Hunter 11364488ca5SDonald HunterThis snippet shows how to declare a queue in a BPF program: 11464488ca5SDonald Hunter 11564488ca5SDonald Hunter.. code-block:: c 11664488ca5SDonald Hunter 11764488ca5SDonald Hunter struct { 11864488ca5SDonald Hunter __uint(type, BPF_MAP_TYPE_QUEUE); 11964488ca5SDonald Hunter __type(value, __u32); 12064488ca5SDonald Hunter __uint(max_entries, 10); 12164488ca5SDonald Hunter } queue SEC(".maps"); 12264488ca5SDonald Hunter 12364488ca5SDonald Hunter 12464488ca5SDonald HunterUserspace 12564488ca5SDonald Hunter--------- 12664488ca5SDonald Hunter 12764488ca5SDonald HunterThis snippet shows how to use libbpf's low-level API to create a queue from 12864488ca5SDonald Hunteruserspace: 12964488ca5SDonald Hunter 13064488ca5SDonald Hunter.. code-block:: c 13164488ca5SDonald Hunter 13264488ca5SDonald Hunter int create_queue() 13364488ca5SDonald Hunter { 13464488ca5SDonald Hunter return bpf_map_create(BPF_MAP_TYPE_QUEUE, 13564488ca5SDonald Hunter "sample_queue", /* name */ 13664488ca5SDonald Hunter 0, /* key size, must be zero */ 13764488ca5SDonald Hunter sizeof(__u32), /* value size */ 13864488ca5SDonald Hunter 10, /* max entries */ 13964488ca5SDonald Hunter NULL); /* create options */ 14064488ca5SDonald Hunter } 14164488ca5SDonald Hunter 14264488ca5SDonald Hunter 14364488ca5SDonald HunterReferences 14464488ca5SDonald Hunter========== 14564488ca5SDonald Hunter 14664488ca5SDonald Hunterhttps://lwn.net/ml/netdev/153986858555.9127.14517764371945179514.stgit@kernel/ 147