147 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. 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/
 |