-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/bpf: Add test for bpf hash map iterators
Two subtests are added. $ ./test_progs -n 4 ... #4/18 bpf_hash_map:OK #4/19 bpf_percpu_hash_map:OK ... Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20200723184120.590916-1-yhs@fb.com
- Loading branch information
Yonghong Song
authored and
Alexei Starovoitov
committed
Jul 26, 2020
1 parent
d8793ac
commit 2a7c2ff
Showing
3 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
tools/testing/selftests/bpf/progs/bpf_iter_bpf_hash_map.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2020 Facebook */ | ||
#include "bpf_iter.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct key_t { | ||
int a; | ||
int b; | ||
int c; | ||
}; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 3); | ||
__type(key, struct key_t); | ||
__type(value, __u64); | ||
} hashmap1 SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 3); | ||
__type(key, __u64); | ||
__type(value, __u64); | ||
} hashmap2 SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 3); | ||
__type(key, struct key_t); | ||
__type(value, __u32); | ||
} hashmap3 SEC(".maps"); | ||
|
||
/* will set before prog run */ | ||
bool in_test_mode = 0; | ||
|
||
/* will collect results during prog run */ | ||
__u32 key_sum_a = 0, key_sum_b = 0, key_sum_c = 0; | ||
__u64 val_sum = 0; | ||
|
||
SEC("iter/bpf_map_elem") | ||
int dump_bpf_hash_map(struct bpf_iter__bpf_map_elem *ctx) | ||
{ | ||
struct seq_file *seq = ctx->meta->seq; | ||
__u32 seq_num = ctx->meta->seq_num; | ||
struct bpf_map *map = ctx->map; | ||
struct key_t *key = ctx->key; | ||
__u64 *val = ctx->value; | ||
|
||
if (in_test_mode) { | ||
/* test mode is used by selftests to | ||
* test functionality of bpf_hash_map iter. | ||
* | ||
* the above hashmap1 will have correct size | ||
* and will be accepted, hashmap2 and hashmap3 | ||
* should be rejected due to smaller key/value | ||
* size. | ||
*/ | ||
if (key == (void *)0 || val == (void *)0) | ||
return 0; | ||
|
||
key_sum_a += key->a; | ||
key_sum_b += key->b; | ||
key_sum_c += key->c; | ||
val_sum += *val; | ||
return 0; | ||
} | ||
|
||
/* non-test mode, the map is prepared with the | ||
* below bpftool command sequence: | ||
* bpftool map create /sys/fs/bpf/m1 type hash \ | ||
* key 12 value 8 entries 3 name map1 | ||
* bpftool map update id 77 key 0 0 0 1 0 0 0 0 0 0 0 1 \ | ||
* value 0 0 0 1 0 0 0 1 | ||
* bpftool map update id 77 key 0 0 0 1 0 0 0 0 0 0 0 2 \ | ||
* value 0 0 0 1 0 0 0 2 | ||
* The bpftool iter command line: | ||
* bpftool iter pin ./bpf_iter_bpf_hash_map.o /sys/fs/bpf/p1 \ | ||
* map id 77 | ||
* The below output will be: | ||
* map dump starts | ||
* 77: (1000000 0 2000000) (200000001000000) | ||
* 77: (1000000 0 1000000) (100000001000000) | ||
* map dump ends | ||
*/ | ||
if (seq_num == 0) | ||
BPF_SEQ_PRINTF(seq, "map dump starts\n"); | ||
|
||
if (key == (void *)0 || val == (void *)0) { | ||
BPF_SEQ_PRINTF(seq, "map dump ends\n"); | ||
return 0; | ||
} | ||
|
||
BPF_SEQ_PRINTF(seq, "%d: (%x %d %x) (%llx)\n", map->id, | ||
key->a, key->b, key->c, *val); | ||
|
||
return 0; | ||
} |
50 changes: 50 additions & 0 deletions
50
tools/testing/selftests/bpf/progs/bpf_iter_bpf_percpu_hash_map.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2020 Facebook */ | ||
#include "bpf_iter.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct key_t { | ||
int a; | ||
int b; | ||
int c; | ||
}; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PERCPU_HASH); | ||
__uint(max_entries, 3); | ||
__type(key, struct key_t); | ||
__type(value, __u32); | ||
} hashmap1 SEC(".maps"); | ||
|
||
/* will set before prog run */ | ||
volatile const __u32 num_cpus = 0; | ||
|
||
/* will collect results during prog run */ | ||
__u32 key_sum_a = 0, key_sum_b = 0, key_sum_c = 0; | ||
__u32 val_sum = 0; | ||
|
||
SEC("iter/bpf_map_elem") | ||
int dump_bpf_percpu_hash_map(struct bpf_iter__bpf_map_elem *ctx) | ||
{ | ||
struct key_t *key = ctx->key; | ||
void *pptr = ctx->value; | ||
__u32 step; | ||
int i; | ||
|
||
if (key == (void *)0 || pptr == (void *)0) | ||
return 0; | ||
|
||
key_sum_a += key->a; | ||
key_sum_b += key->b; | ||
key_sum_c += key->c; | ||
|
||
step = 8; | ||
for (i = 0; i < num_cpus; i++) { | ||
val_sum += *(__u32 *)pptr; | ||
pptr += step; | ||
} | ||
return 0; | ||
} |