linux/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3#include <stdio.h>
   4#include <errno.h>
   5#include <string.h>
   6
   7#include <bpf/bpf.h>
   8#include <bpf/libbpf.h>
   9
  10#include <test_maps.h>
  11
  12static void map_batch_update(int map_fd, __u32 max_entries, int *keys,
  13                             int *values)
  14{
  15        int i, err;
  16        DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,
  17                .elem_flags = 0,
  18                .flags = 0,
  19        );
  20
  21        for (i = 0; i < max_entries; i++) {
  22                keys[i] = i;
  23                values[i] = i + 1;
  24        }
  25
  26        err = bpf_map_update_batch(map_fd, keys, values, &max_entries, &opts);
  27        CHECK(err, "bpf_map_update_batch()", "error:%s\n", strerror(errno));
  28}
  29
  30static void map_batch_verify(int *visited, __u32 max_entries,
  31                             int *keys, int *values)
  32{
  33        int i;
  34
  35        memset(visited, 0, max_entries * sizeof(*visited));
  36        for (i = 0; i < max_entries; i++) {
  37                CHECK(keys[i] + 1 != values[i], "key/value checking",
  38                      "error: i %d key %d value %d\n", i, keys[i], values[i]);
  39                visited[i] = 1;
  40        }
  41        for (i = 0; i < max_entries; i++) {
  42                CHECK(visited[i] != 1, "visited checking",
  43                      "error: keys array at index %d missing\n", i);
  44        }
  45}
  46
  47void test_array_map_batch_ops(void)
  48{
  49        struct bpf_create_map_attr xattr = {
  50                .name = "array_map",
  51                .map_type = BPF_MAP_TYPE_ARRAY,
  52                .key_size = sizeof(int),
  53                .value_size = sizeof(int),
  54        };
  55        int map_fd, *keys, *values, *visited;
  56        __u32 count, total, total_success;
  57        const __u32 max_entries = 10;
  58        bool nospace_err;
  59        __u64 batch = 0;
  60        int err, step;
  61        DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,
  62                .elem_flags = 0,
  63                .flags = 0,
  64        );
  65
  66        xattr.max_entries = max_entries;
  67        map_fd = bpf_create_map_xattr(&xattr);
  68        CHECK(map_fd == -1,
  69              "bpf_create_map_xattr()", "error:%s\n", strerror(errno));
  70
  71        keys = malloc(max_entries * sizeof(int));
  72        values = malloc(max_entries * sizeof(int));
  73        visited = malloc(max_entries * sizeof(int));
  74        CHECK(!keys || !values || !visited, "malloc()", "error:%s\n",
  75              strerror(errno));
  76
  77        /* populate elements to the map */
  78        map_batch_update(map_fd, max_entries, keys, values);
  79
  80        /* test 1: lookup in a loop with various steps. */
  81        total_success = 0;
  82        for (step = 1; step < max_entries; step++) {
  83                map_batch_update(map_fd, max_entries, keys, values);
  84                map_batch_verify(visited, max_entries, keys, values);
  85                memset(keys, 0, max_entries * sizeof(*keys));
  86                memset(values, 0, max_entries * sizeof(*values));
  87                batch = 0;
  88                total = 0;
  89                /* iteratively lookup/delete elements with 'step'
  90                 * elements each.
  91                 */
  92                count = step;
  93                nospace_err = false;
  94                while (true) {
  95                        err = bpf_map_lookup_batch(map_fd,
  96                                                total ? &batch : NULL, &batch,
  97                                                keys + total,
  98                                                values + total,
  99                                                &count, &opts);
 100
 101                        CHECK((err && errno != ENOENT), "lookup with steps",
 102                              "error: %s\n", strerror(errno));
 103
 104                        total += count;
 105                        if (err)
 106                                break;
 107
 108                }
 109
 110                if (nospace_err == true)
 111                        continue;
 112
 113                CHECK(total != max_entries, "lookup with steps",
 114                      "total = %u, max_entries = %u\n", total, max_entries);
 115
 116                map_batch_verify(visited, max_entries, keys, values);
 117
 118                total_success++;
 119        }
 120
 121        CHECK(total_success == 0, "check total_success",
 122              "unexpected failure\n");
 123
 124        printf("%s:PASS\n", __func__);
 125
 126        free(keys);
 127        free(values);
 128        free(visited);
 129}
 130