brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 2c4ef60 Raw
99 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (C) 2023. Huawei Technologies Co., Ltd */3#include <test_progs.h>4 5#include "normal_map_btf.skel.h"6#include "map_in_map_btf.skel.h"7 8static void do_test_normal_map_btf(void)9{10	struct normal_map_btf *skel;11	int i, err, new_fd = -1;12	int map_fd_arr[64];13 14	skel = normal_map_btf__open_and_load();15	if (!ASSERT_OK_PTR(skel, "open_load"))16		return;17 18	err = normal_map_btf__attach(skel);19	if (!ASSERT_OK(err, "attach"))20		goto out;21 22	skel->bss->pid = getpid();23	usleep(1);24	ASSERT_TRUE(skel->bss->done, "done");25 26	/* Use percpu_array to slow bpf_map_free_deferred() down.27	 * The memory allocation may fail, so doesn't check the returned fd.28	 */29	for (i = 0; i < ARRAY_SIZE(map_fd_arr); i++)30		map_fd_arr[i] = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, NULL, 4, 4, 256, NULL);31 32	/* Close array fd later */33	new_fd = dup(bpf_map__fd(skel->maps.array));34out:35	normal_map_btf__destroy(skel);36	if (new_fd < 0)37		return;38	/* Use kern_sync_rcu() to wait for the start of the free of the bpf39	 * program and use an assumed delay to wait for the release of the map40	 * btf which is held by other maps (e.g, bss). After that, array map41	 * holds the last reference of map btf.42	 */43	kern_sync_rcu();44	usleep(4000);45	/* Spawn multiple kworkers to delay the invocation of46	 * bpf_map_free_deferred() for array map.47	 */48	for (i = 0; i < ARRAY_SIZE(map_fd_arr); i++) {49		if (map_fd_arr[i] < 0)50			continue;51		close(map_fd_arr[i]);52	}53	close(new_fd);54}55 56static void do_test_map_in_map_btf(void)57{58	int err, zero = 0, new_fd = -1;59	struct map_in_map_btf *skel;60 61	skel = map_in_map_btf__open_and_load();62	if (!ASSERT_OK_PTR(skel, "open_load"))63		return;64 65	err = map_in_map_btf__attach(skel);66	if (!ASSERT_OK(err, "attach"))67		goto out;68 69	skel->bss->pid = getpid();70	usleep(1);71	ASSERT_TRUE(skel->bss->done, "done");72 73	/* Close inner_array fd later */74	new_fd = dup(bpf_map__fd(skel->maps.inner_array));75	/* Defer the free of inner_array */76	err = bpf_map__delete_elem(skel->maps.outer_array, &zero, sizeof(zero), 0);77	ASSERT_OK(err, "delete inner map");78out:79	map_in_map_btf__destroy(skel);80	if (new_fd < 0)81		return;82	/* Use kern_sync_rcu() to wait for the start of the free of the bpf83	 * program and use an assumed delay to wait for the free of the outer84	 * map and the release of map btf. After that, inner map holds the last85	 * reference of map btf.86	 */87	kern_sync_rcu();88	usleep(10000);89	close(new_fd);90}91 92void test_map_btf(void)93{94	if (test__start_subtest("array_btf"))95		do_test_normal_map_btf();96	if (test__start_subtest("inner_array_btf"))97		do_test_map_in_map_btf();98}99