summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2016-02-02 01:39:56 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-06 03:34:36 -0500
commite15596717948c95587a0b15363030283c126c23a (patch)
tree14e130e94d3576dfdf5d940541cf867e765fc6a6 /samples
parent15a07b33814d14ca817887dbea8530728dc0fbe4 (diff)
samples/bpf: unit test for BPF_MAP_TYPE_PERCPU_HASH
A sanity test for BPF_MAP_TYPE_PERCPU_HASH. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/test_maps.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c
index 6299ee95cd11..5f5fe5332148 100644
--- a/samples/bpf/test_maps.c
+++ b/samples/bpf/test_maps.c
@@ -89,6 +89,100 @@ static void test_hashmap_sanity(int i, void *data)
89 close(map_fd); 89 close(map_fd);
90} 90}
91 91
92/* sanity tests for percpu map API */
93static void test_percpu_hashmap_sanity(int task, void *data)
94{
95 long long key, next_key;
96 int expected_key_mask = 0;
97 unsigned int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
98 long long value[nr_cpus];
99 int map_fd, i;
100
101 map_fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
102 sizeof(value[0]), 2);
103 if (map_fd < 0) {
104 printf("failed to create hashmap '%s'\n", strerror(errno));
105 exit(1);
106 }
107
108 for (i = 0; i < nr_cpus; i++)
109 value[i] = i + 100;
110 key = 1;
111 /* insert key=1 element */
112 assert(!(expected_key_mask & key));
113 assert(bpf_update_elem(map_fd, &key, value, BPF_ANY) == 0);
114 expected_key_mask |= key;
115
116 /* BPF_NOEXIST means: add new element if it doesn't exist */
117 assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == -1 &&
118 /* key=1 already exists */
119 errno == EEXIST);
120
121 /* -1 is an invalid flag */
122 assert(bpf_update_elem(map_fd, &key, value, -1) == -1 &&
123 errno == EINVAL);
124
125 /* check that key=1 can be found. value could be 0 if the lookup
126 * was run from a different cpu.
127 */
128 value[0] = 1;
129 assert(bpf_lookup_elem(map_fd, &key, value) == 0 && value[0] == 100);
130
131 key = 2;
132 /* check that key=2 is not found */
133 assert(bpf_lookup_elem(map_fd, &key, value) == -1 && errno == ENOENT);
134
135 /* BPF_EXIST means: update existing element */
136 assert(bpf_update_elem(map_fd, &key, value, BPF_EXIST) == -1 &&
137 /* key=2 is not there */
138 errno == ENOENT);
139
140 /* insert key=2 element */
141 assert(!(expected_key_mask & key));
142 assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == 0);
143 expected_key_mask |= key;
144
145 /* key=1 and key=2 were inserted, check that key=0 cannot be inserted
146 * due to max_entries limit
147 */
148 key = 0;
149 assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == -1 &&
150 errno == E2BIG);
151
152 /* check that key = 0 doesn't exist */
153 assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
154
155 /* iterate over two elements */
156 while (!bpf_get_next_key(map_fd, &key, &next_key)) {
157 assert((expected_key_mask & next_key) == next_key);
158 expected_key_mask &= ~next_key;
159
160 assert(bpf_lookup_elem(map_fd, &next_key, value) == 0);
161 for (i = 0; i < nr_cpus; i++)
162 assert(value[i] == i + 100);
163
164 key = next_key;
165 }
166 assert(errno == ENOENT);
167
168 /* Update with BPF_EXIST */
169 key = 1;
170 assert(bpf_update_elem(map_fd, &key, value, BPF_EXIST) == 0);
171
172 /* delete both elements */
173 key = 1;
174 assert(bpf_delete_elem(map_fd, &key) == 0);
175 key = 2;
176 assert(bpf_delete_elem(map_fd, &key) == 0);
177 assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
178
179 key = 0;
180 /* check that map is empty */
181 assert(bpf_get_next_key(map_fd, &key, &next_key) == -1 &&
182 errno == ENOENT);
183 close(map_fd);
184}
185
92static void test_arraymap_sanity(int i, void *data) 186static void test_arraymap_sanity(int i, void *data)
93{ 187{
94 int key, next_key, map_fd; 188 int key, next_key, map_fd;
@@ -209,6 +303,7 @@ static void run_parallel(int tasks, void (*fn)(int i, void *data), void *data)
209static void test_map_stress(void) 303static void test_map_stress(void)
210{ 304{
211 run_parallel(100, test_hashmap_sanity, NULL); 305 run_parallel(100, test_hashmap_sanity, NULL);
306 run_parallel(100, test_percpu_hashmap_sanity, NULL);
212 run_parallel(100, test_arraymap_sanity, NULL); 307 run_parallel(100, test_arraymap_sanity, NULL);
213} 308}
214 309
@@ -282,6 +377,7 @@ static void test_map_parallel(void)
282int main(void) 377int main(void)
283{ 378{
284 test_hashmap_sanity(0, NULL); 379 test_hashmap_sanity(0, NULL);
380 test_percpu_hashmap_sanity(0, NULL);
285 test_arraymap_sanity(0, NULL); 381 test_arraymap_sanity(0, NULL);
286 test_map_large(); 382 test_map_large();
287 test_map_parallel(); 383 test_map_parallel();