0001 .. SPDX-License-Identifier: GPL-2.0-only
0002 .. Copyright (C) 2022 Red Hat, Inc.
0003
0004 ===============================================
0005 BPF_MAP_TYPE_HASH, with PERCPU and LRU Variants
0006 ===============================================
0007
0008 .. note::
0009 - ``BPF_MAP_TYPE_HASH`` was introduced in kernel version 3.19
0010 - ``BPF_MAP_TYPE_PERCPU_HASH`` was introduced in version 4.6
0011 - Both ``BPF_MAP_TYPE_LRU_HASH`` and ``BPF_MAP_TYPE_LRU_PERCPU_HASH``
0012 were introduced in version 4.10
0013
0014 ``BPF_MAP_TYPE_HASH`` and ``BPF_MAP_TYPE_PERCPU_HASH`` provide general
0015 purpose hash map storage. Both the key and the value can be structs,
0016 allowing for composite keys and values.
0017
0018 The kernel is responsible for allocating and freeing key/value pairs, up
0019 to the max_entries limit that you specify. Hash maps use pre-allocation
0020 of hash table elements by default. The ``BPF_F_NO_PREALLOC`` flag can be
0021 used to disable pre-allocation when it is too memory expensive.
0022
0023 ``BPF_MAP_TYPE_PERCPU_HASH`` provides a separate value slot per
0024 CPU. The per-cpu values are stored internally in an array.
0025
0026 The ``BPF_MAP_TYPE_LRU_HASH`` and ``BPF_MAP_TYPE_LRU_PERCPU_HASH``
0027 variants add LRU semantics to their respective hash tables. An LRU hash
0028 will automatically evict the least recently used entries when the hash
0029 table reaches capacity. An LRU hash maintains an internal LRU list that
0030 is used to select elements for eviction. This internal LRU list is
0031 shared across CPUs but it is possible to request a per CPU LRU list with
0032 the ``BPF_F_NO_COMMON_LRU`` flag when calling ``bpf_map_create``.
0033
0034 Usage
0035 =====
0036
0037 .. c:function::
0038 long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
0039
0040 Hash entries can be added or updated using the ``bpf_map_update_elem()``
0041 helper. This helper replaces existing elements atomically. The ``flags``
0042 parameter can be used to control the update behaviour:
0043
0044 - ``BPF_ANY`` will create a new element or update an existing element
0045 - ``BPF_NOEXIST`` will create a new element only if one did not already
0046 exist
0047 - ``BPF_EXIST`` will update an existing element
0048
0049 ``bpf_map_update_elem()`` returns 0 on success, or negative error in
0050 case of failure.
0051
0052 .. c:function::
0053 void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
0054
0055 Hash entries can be retrieved using the ``bpf_map_lookup_elem()``
0056 helper. This helper returns a pointer to the value associated with
0057 ``key``, or ``NULL`` if no entry was found.
0058
0059 .. c:function::
0060 long bpf_map_delete_elem(struct bpf_map *map, const void *key)
0061
0062 Hash entries can be deleted using the ``bpf_map_delete_elem()``
0063 helper. This helper will return 0 on success, or negative error in case
0064 of failure.
0065
0066 Per CPU Hashes
0067 --------------
0068
0069 For ``BPF_MAP_TYPE_PERCPU_HASH`` and ``BPF_MAP_TYPE_LRU_PERCPU_HASH``
0070 the ``bpf_map_update_elem()`` and ``bpf_map_lookup_elem()`` helpers
0071 automatically access the hash slot for the current CPU.
0072
0073 .. c:function::
0074 void *bpf_map_lookup_percpu_elem(struct bpf_map *map, const void *key, u32 cpu)
0075
0076 The ``bpf_map_lookup_percpu_elem()`` helper can be used to lookup the
0077 value in the hash slot for a specific CPU. Returns value associated with
0078 ``key`` on ``cpu`` , or ``NULL`` if no entry was found or ``cpu`` is
0079 invalid.
0080
0081 Concurrency
0082 -----------
0083
0084 Values stored in ``BPF_MAP_TYPE_HASH`` can be accessed concurrently by
0085 programs running on different CPUs. Since Kernel version 5.1, the BPF
0086 infrastructure provides ``struct bpf_spin_lock`` to synchronise access.
0087 See ``tools/testing/selftests/bpf/progs/test_spin_lock.c``.
0088
0089 Userspace
0090 ---------
0091
0092 .. c:function::
0093 int bpf_map_get_next_key(int fd, const void *cur_key, void *next_key)
0094
0095 In userspace, it is possible to iterate through the keys of a hash using
0096 libbpf's ``bpf_map_get_next_key()`` function. The first key can be fetched by
0097 calling ``bpf_map_get_next_key()`` with ``cur_key`` set to
0098 ``NULL``. Subsequent calls will fetch the next key that follows the
0099 current key. ``bpf_map_get_next_key()`` returns 0 on success, -ENOENT if
0100 cur_key is the last key in the hash, or negative error in case of
0101 failure.
0102
0103 Note that if ``cur_key`` gets deleted then ``bpf_map_get_next_key()``
0104 will instead return the *first* key in the hash table which is
0105 undesirable. It is recommended to use batched lookup if there is going
0106 to be key deletion intermixed with ``bpf_map_get_next_key()``.
0107
0108 Examples
0109 ========
0110
0111 Please see the ``tools/testing/selftests/bpf`` directory for functional
0112 examples. The code snippets below demonstrates API usage.
0113
0114 This example shows how to declare an LRU Hash with a struct key and a
0115 struct value.
0116
0117 .. code-block:: c
0118
0119 #include <linux/bpf.h>
0120 #include <bpf/bpf_helpers.h>
0121
0122 struct key {
0123 __u32 srcip;
0124 };
0125
0126 struct value {
0127 __u64 packets;
0128 __u64 bytes;
0129 };
0130
0131 struct {
0132 __uint(type, BPF_MAP_TYPE_LRU_HASH);
0133 __uint(max_entries, 32);
0134 __type(key, struct key);
0135 __type(value, struct value);
0136 } packet_stats SEC(".maps");
0137
0138 This example shows how to create or update hash values using atomic
0139 instructions:
0140
0141 .. code-block:: c
0142
0143 static void update_stats(__u32 srcip, int bytes)
0144 {
0145 struct key key = {
0146 .srcip = srcip,
0147 };
0148 struct value *value = bpf_map_lookup_elem(&packet_stats, &key);
0149
0150 if (value) {
0151 __sync_fetch_and_add(&value->packets, 1);
0152 __sync_fetch_and_add(&value->bytes, bytes);
0153 } else {
0154 struct value newval = { 1, bytes };
0155
0156 bpf_map_update_elem(&packet_stats, &key, &newval, BPF_NOEXIST);
0157 }
0158 }
0159
0160 Userspace walking the map elements from the map declared above:
0161
0162 .. code-block:: c
0163
0164 #include <bpf/libbpf.h>
0165 #include <bpf/bpf.h>
0166
0167 static void walk_hash_elements(int map_fd)
0168 {
0169 struct key *cur_key = NULL;
0170 struct key next_key;
0171 struct value value;
0172 int err;
0173
0174 for (;;) {
0175 err = bpf_map_get_next_key(map_fd, cur_key, &next_key);
0176 if (err)
0177 break;
0178
0179 bpf_map_lookup_elem(map_fd, &next_key, &value);
0180
0181 // Use key and value here
0182
0183 cur_key = &next_key;
0184 }
0185 }