0001
0002
0003
0004 #include <test_progs.h>
0005 #include "test_map_init.skel.h"
0006
0007 #define TEST_VALUE 0x1234
0008 #define FILL_VALUE 0xdeadbeef
0009
0010 static int nr_cpus;
0011 static int duration;
0012
0013 typedef unsigned long long map_key_t;
0014 typedef unsigned long long map_value_t;
0015 typedef struct {
0016 map_value_t v;
0017 } __bpf_percpu_val_align pcpu_map_value_t;
0018
0019
0020 static int map_populate(int map_fd, int num)
0021 {
0022 pcpu_map_value_t value[nr_cpus];
0023 int i, err;
0024 map_key_t key;
0025
0026 for (i = 0; i < nr_cpus; i++)
0027 bpf_percpu(value, i) = FILL_VALUE;
0028
0029 for (key = 1; key <= num; key++) {
0030 err = bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST);
0031 if (!ASSERT_OK(err, "bpf_map_update_elem"))
0032 return -1;
0033 }
0034
0035 return 0;
0036 }
0037
0038 static struct test_map_init *setup(enum bpf_map_type map_type, int map_sz,
0039 int *map_fd, int populate)
0040 {
0041 struct test_map_init *skel;
0042 int err;
0043
0044 skel = test_map_init__open();
0045 if (!ASSERT_OK_PTR(skel, "skel_open"))
0046 return NULL;
0047
0048 err = bpf_map__set_type(skel->maps.hashmap1, map_type);
0049 if (!ASSERT_OK(err, "bpf_map__set_type"))
0050 goto error;
0051
0052 err = bpf_map__set_max_entries(skel->maps.hashmap1, map_sz);
0053 if (!ASSERT_OK(err, "bpf_map__set_max_entries"))
0054 goto error;
0055
0056 err = test_map_init__load(skel);
0057 if (!ASSERT_OK(err, "skel_load"))
0058 goto error;
0059
0060 *map_fd = bpf_map__fd(skel->maps.hashmap1);
0061 if (CHECK(*map_fd < 0, "bpf_map__fd", "failed\n"))
0062 goto error;
0063
0064 err = map_populate(*map_fd, populate);
0065 if (!ASSERT_OK(err, "map_populate"))
0066 goto error_map;
0067
0068 return skel;
0069
0070 error_map:
0071 close(*map_fd);
0072 error:
0073 test_map_init__destroy(skel);
0074 return NULL;
0075 }
0076
0077
0078 static int prog_run_insert_elem(struct test_map_init *skel, map_key_t key,
0079 map_value_t value)
0080 {
0081 struct test_map_init__bss *bss;
0082
0083 bss = skel->bss;
0084
0085 bss->inKey = key;
0086 bss->inValue = value;
0087 bss->inPid = getpid();
0088
0089 if (!ASSERT_OK(test_map_init__attach(skel), "skel_attach"))
0090 return -1;
0091
0092
0093 syscall(__NR_getpgid);
0094
0095 test_map_init__detach(skel);
0096
0097 return 0;
0098 }
0099
0100 static int check_values_one_cpu(pcpu_map_value_t *value, map_value_t expected)
0101 {
0102 int i, nzCnt = 0;
0103 map_value_t val;
0104
0105 for (i = 0; i < nr_cpus; i++) {
0106 val = bpf_percpu(value, i);
0107 if (val) {
0108 if (CHECK(val != expected, "map value",
0109 "unexpected for cpu %d: 0x%llx\n", i, val))
0110 return -1;
0111 nzCnt++;
0112 }
0113 }
0114
0115 if (CHECK(nzCnt != 1, "map value", "set for %d CPUs instead of 1!\n",
0116 nzCnt))
0117 return -1;
0118
0119 return 0;
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129 static void test_pcpu_map_init(void)
0130 {
0131 pcpu_map_value_t value[nr_cpus];
0132 struct test_map_init *skel;
0133 int map_fd, err;
0134 map_key_t key;
0135
0136
0137 skel = setup(BPF_MAP_TYPE_PERCPU_HASH, 1, &map_fd, 1);
0138 if (!ASSERT_OK_PTR(skel, "prog_setup"))
0139 return;
0140
0141
0142 key = 1;
0143 err = bpf_map_delete_elem(map_fd, &key);
0144 if (!ASSERT_OK(err, "bpf_map_delete_elem"))
0145 goto cleanup;
0146
0147
0148 err = prog_run_insert_elem(skel, key, TEST_VALUE);
0149 if (!ASSERT_OK(err, "prog_run_insert_elem"))
0150 goto cleanup;
0151
0152
0153 err = bpf_map_lookup_elem(map_fd, &key, value);
0154 if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
0155 goto cleanup;
0156
0157
0158 check_values_one_cpu(value, TEST_VALUE);
0159
0160 cleanup:
0161 test_map_init__destroy(skel);
0162 }
0163
0164
0165
0166
0167
0168
0169 static void test_pcpu_lru_map_init(void)
0170 {
0171 pcpu_map_value_t value[nr_cpus];
0172 struct test_map_init *skel;
0173 int map_fd, err;
0174 map_key_t key;
0175
0176
0177
0178
0179 skel = setup(BPF_MAP_TYPE_LRU_PERCPU_HASH, 2, &map_fd, 2);
0180 if (!ASSERT_OK_PTR(skel, "prog_setup"))
0181 return;
0182
0183
0184 key = 3;
0185 err = prog_run_insert_elem(skel, key, TEST_VALUE);
0186 if (!ASSERT_OK(err, "prog_run_insert_elem"))
0187 goto cleanup;
0188
0189
0190 err = bpf_map_lookup_elem(map_fd, &key, value);
0191 if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
0192 goto cleanup;
0193
0194
0195 check_values_one_cpu(value, TEST_VALUE);
0196
0197 cleanup:
0198 test_map_init__destroy(skel);
0199 }
0200
0201 void test_map_init(void)
0202 {
0203 nr_cpus = bpf_num_possible_cpus();
0204 if (nr_cpus <= 1) {
0205 printf("%s:SKIP: >1 cpu needed for this test\n", __func__);
0206 test__skip();
0207 return;
0208 }
0209
0210 if (test__start_subtest("pcpu_map_init"))
0211 test_pcpu_map_init();
0212 if (test__start_subtest("pcpu_lru_map_init"))
0213 test_pcpu_lru_map_init();
0214 }