On Fri, 2024-11-15 at 00:46 +0000, Anton Protopopov wrote: [...] > @@ -0,0 +1,374 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <test_progs.h> > + > +#include <linux/btf.h> > +#include <sys/syscall.h> > +#include <bpf/bpf.h> > + > +static inline int _bpf_map_create(void) > +{ > + static union bpf_attr attr = { > + .map_type = BPF_MAP_TYPE_ARRAY, > + .key_size = 4, > + .value_size = 8, > + .max_entries = 1, > + }; > + > + return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); > +} > + > +#define BTF_INFO_ENC(kind, kind_flag, vlen) \ > + ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN)) > +#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type) > +#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \ > + ((encoding) << 24 | (bits_offset) << 16 | (nr_bits)) > +#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \ > + BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \ > + BTF_INT_ENC(encoding, bits_offset, bits) Nit: these macro are already defined in tools/testing/selftests/bpf/test_btf.h . > + > +static int _btf_create(void) > +{ > + struct btf_blob { > + struct btf_header btf_hdr; > + __u32 types[8]; > + __u32 str; > + } raw_btf = { > + .btf_hdr = { > + .magic = BTF_MAGIC, > + .version = BTF_VERSION, > + .hdr_len = sizeof(struct btf_header), > + .type_len = sizeof(__u32) * 8, > + .str_off = sizeof(__u32) * 8, > + .str_len = sizeof(__u32), Nit: offsetof(struct btf_blob, str), sizeof(raw_btf.str), sizeof(raw_btf.types) are legal in this position. > + }, > + .types = { > + /* long */ > + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8), /* [1] */ > + /* unsigned long */ > + BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ > + }, > + }; > + static union bpf_attr attr = { > + .btf_size = sizeof(raw_btf), > + }; > + > + attr.btf = (long)&raw_btf; > + > + return syscall(__NR_bpf, BPF_BTF_LOAD, &attr, sizeof(attr)); > +} [...] > +static void check_fd_array_cnt__fd_array_ok(void) > +{ > + int extra_fds[128]; > + __u32 map_ids[16]; > + __u32 nr_map_ids; > + int prog_fd; > + > + extra_fds[0] = _bpf_map_create(); > + if (!ASSERT_GE(extra_fds[0], 0, "_bpf_map_create")) > + return; > + extra_fds[1] = _bpf_map_create(); > + if (!ASSERT_GE(extra_fds[1], 0, "_bpf_map_create")) > + return; > + prog_fd = load_test_prog(extra_fds, 2); > + if (!ASSERT_GE(prog_fd, 0, "BPF_PROG_LOAD")) > + return; > + nr_map_ids = ARRAY_SIZE(map_ids); > + if (!check_expected_map_ids(prog_fd, 3, map_ids, &nr_map_ids)) Nit: should probably close prog_fd and extra_fds (and in tests below). > + return; > + > + /* maps should still exist when original file descriptors are closed */ > + close(extra_fds[0]); > + close(extra_fds[1]); > + if (!ASSERT_EQ(map_exists(map_ids[0]), true, "map_ids[0] should exist")) > + return; > + if (!ASSERT_EQ(map_exists(map_ids[1]), true, "map_ids[1] should exist")) > + return; > + > + close(prog_fd); > +} [...]