The linked_list tests use macros and function pointers to reduce code duplication. Earlier in the series, bpf_list_push_{front,back} were modified to be macros, expanding to invoke actual kfuncs bpf_list_push_{front,back}_impl. Due to this change, a code snippet like: void (*p)(void *, void *) = (void *)&bpf_list_##op; p(hexpr, nexpr); meant to do bpf_list_push_{front,back}(hexpr, nexpr), will no longer work as it's no longer valid to do &bpf_list_push_{front,back} since they're no longer functions. This patch fixes issues of this type, along with two other minor changes - one improvement and one fix - both related to the node argument to list_push_{front,back}. * The fix: migration of list_push tests away from (void *, void *) func ptr uncovered that some tests were incorrectly passing pointer to node, not pointer to struct bpf_list_node within the node. This patch fixes such issues (CHECK(..., f) -> CHECK(..., &f->node)) * The improvement: In linked_list tests, the struct foo type has two list_node fields: node and node2, at byte offsets 0 and 40 within the struct, respectively. Currently node is used in ~all tests involving struct foo and lists. The verifier needs to do some work to account for the offset of bpf_list_node within the node type, so using node2 instead of node exercises that logic more in the tests. This patch migrates linked_list tests to use node2 instead of node. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> Link: https://lore.kernel.org/r/20230415201811.343116-7-davemarchevsky@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
57 lines
1.1 KiB
C
57 lines
1.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#ifndef LINKED_LIST_H
|
|
#define LINKED_LIST_H
|
|
|
|
#include <vmlinux.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include "bpf_experimental.h"
|
|
|
|
struct bar {
|
|
struct bpf_list_node node;
|
|
int data;
|
|
};
|
|
|
|
struct foo {
|
|
struct bpf_list_node node;
|
|
struct bpf_list_head head __contains(bar, node);
|
|
struct bpf_spin_lock lock;
|
|
int data;
|
|
struct bpf_list_node node2;
|
|
};
|
|
|
|
struct map_value {
|
|
struct bpf_spin_lock lock;
|
|
int data;
|
|
struct bpf_list_head head __contains(foo, node2);
|
|
};
|
|
|
|
struct array_map {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
__type(key, int);
|
|
__type(value, struct map_value);
|
|
__uint(max_entries, 1);
|
|
};
|
|
|
|
struct array_map array_map SEC(".maps");
|
|
struct array_map inner_map SEC(".maps");
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
|
|
__uint(max_entries, 1);
|
|
__type(key, int);
|
|
__type(value, int);
|
|
__array(values, struct array_map);
|
|
} map_of_maps SEC(".maps") = {
|
|
.values = {
|
|
[0] = &inner_map,
|
|
},
|
|
};
|
|
|
|
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
|
|
|
|
private(A) struct bpf_spin_lock glock;
|
|
private(A) struct bpf_list_head ghead __contains(foo, node2);
|
|
private(B) struct bpf_spin_lock glock2;
|
|
|
|
#endif
|