brintos

brintos / linux-shallow public Read only

0
0
Text · 19.7 KiB · 960c932 Raw
768 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <test_progs.h>3#include "kprobe_multi.skel.h"4#include "trace_helpers.h"5#include "kprobe_multi_empty.skel.h"6#include "kprobe_multi_override.skel.h"7#include "kprobe_multi_session.skel.h"8#include "kprobe_multi_session_cookie.skel.h"9#include "bpf/libbpf_internal.h"10#include "bpf/hashmap.h"11 12static void kprobe_multi_test_run(struct kprobe_multi *skel, bool test_return)13{14	LIBBPF_OPTS(bpf_test_run_opts, topts);15	int err, prog_fd;16 17	prog_fd = bpf_program__fd(skel->progs.trigger);18	err = bpf_prog_test_run_opts(prog_fd, &topts);19	ASSERT_OK(err, "test_run");20	ASSERT_EQ(topts.retval, 0, "test_run");21 22	ASSERT_EQ(skel->bss->kprobe_test1_result, 1, "kprobe_test1_result");23	ASSERT_EQ(skel->bss->kprobe_test2_result, 1, "kprobe_test2_result");24	ASSERT_EQ(skel->bss->kprobe_test3_result, 1, "kprobe_test3_result");25	ASSERT_EQ(skel->bss->kprobe_test4_result, 1, "kprobe_test4_result");26	ASSERT_EQ(skel->bss->kprobe_test5_result, 1, "kprobe_test5_result");27	ASSERT_EQ(skel->bss->kprobe_test6_result, 1, "kprobe_test6_result");28	ASSERT_EQ(skel->bss->kprobe_test7_result, 1, "kprobe_test7_result");29	ASSERT_EQ(skel->bss->kprobe_test8_result, 1, "kprobe_test8_result");30 31	if (test_return) {32		ASSERT_EQ(skel->bss->kretprobe_test1_result, 1, "kretprobe_test1_result");33		ASSERT_EQ(skel->bss->kretprobe_test2_result, 1, "kretprobe_test2_result");34		ASSERT_EQ(skel->bss->kretprobe_test3_result, 1, "kretprobe_test3_result");35		ASSERT_EQ(skel->bss->kretprobe_test4_result, 1, "kretprobe_test4_result");36		ASSERT_EQ(skel->bss->kretprobe_test5_result, 1, "kretprobe_test5_result");37		ASSERT_EQ(skel->bss->kretprobe_test6_result, 1, "kretprobe_test6_result");38		ASSERT_EQ(skel->bss->kretprobe_test7_result, 1, "kretprobe_test7_result");39		ASSERT_EQ(skel->bss->kretprobe_test8_result, 1, "kretprobe_test8_result");40	}41}42 43static void test_skel_api(void)44{45	struct kprobe_multi *skel = NULL;46	int err;47 48	skel = kprobe_multi__open_and_load();49	if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))50		goto cleanup;51 52	skel->bss->pid = getpid();53	err = kprobe_multi__attach(skel);54	if (!ASSERT_OK(err, "kprobe_multi__attach"))55		goto cleanup;56 57	kprobe_multi_test_run(skel, true);58 59cleanup:60	kprobe_multi__destroy(skel);61}62 63static void test_link_api(struct bpf_link_create_opts *opts)64{65	int prog_fd, link1_fd = -1, link2_fd = -1;66	struct kprobe_multi *skel = NULL;67 68	skel = kprobe_multi__open_and_load();69	if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))70		goto cleanup;71 72	skel->bss->pid = getpid();73	prog_fd = bpf_program__fd(skel->progs.test_kprobe);74	link1_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);75	if (!ASSERT_GE(link1_fd, 0, "link_fd"))76		goto cleanup;77 78	opts->kprobe_multi.flags = BPF_F_KPROBE_MULTI_RETURN;79	prog_fd = bpf_program__fd(skel->progs.test_kretprobe);80	link2_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);81	if (!ASSERT_GE(link2_fd, 0, "link_fd"))82		goto cleanup;83 84	kprobe_multi_test_run(skel, true);85 86cleanup:87	if (link1_fd != -1)88		close(link1_fd);89	if (link2_fd != -1)90		close(link2_fd);91	kprobe_multi__destroy(skel);92}93 94#define GET_ADDR(__sym, __addr) ({					\95	__addr = ksym_get_addr(__sym);					\96	if (!ASSERT_NEQ(__addr, 0, "kallsyms load failed for " #__sym))	\97		return;							\98})99 100static void test_link_api_addrs(void)101{102	LIBBPF_OPTS(bpf_link_create_opts, opts);103	unsigned long long addrs[8];104 105	GET_ADDR("bpf_fentry_test1", addrs[0]);106	GET_ADDR("bpf_fentry_test2", addrs[1]);107	GET_ADDR("bpf_fentry_test3", addrs[2]);108	GET_ADDR("bpf_fentry_test4", addrs[3]);109	GET_ADDR("bpf_fentry_test5", addrs[4]);110	GET_ADDR("bpf_fentry_test6", addrs[5]);111	GET_ADDR("bpf_fentry_test7", addrs[6]);112	GET_ADDR("bpf_fentry_test8", addrs[7]);113 114	opts.kprobe_multi.addrs = (const unsigned long*) addrs;115	opts.kprobe_multi.cnt = ARRAY_SIZE(addrs);116	test_link_api(&opts);117}118 119static void test_link_api_syms(void)120{121	LIBBPF_OPTS(bpf_link_create_opts, opts);122	const char *syms[8] = {123		"bpf_fentry_test1",124		"bpf_fentry_test2",125		"bpf_fentry_test3",126		"bpf_fentry_test4",127		"bpf_fentry_test5",128		"bpf_fentry_test6",129		"bpf_fentry_test7",130		"bpf_fentry_test8",131	};132 133	opts.kprobe_multi.syms = syms;134	opts.kprobe_multi.cnt = ARRAY_SIZE(syms);135	test_link_api(&opts);136}137 138static void139test_attach_api(const char *pattern, struct bpf_kprobe_multi_opts *opts)140{141	struct bpf_link *link1 = NULL, *link2 = NULL;142	struct kprobe_multi *skel = NULL;143 144	skel = kprobe_multi__open_and_load();145	if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))146		goto cleanup;147 148	skel->bss->pid = getpid();149	link1 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,150						      pattern, opts);151	if (!ASSERT_OK_PTR(link1, "bpf_program__attach_kprobe_multi_opts"))152		goto cleanup;153 154	if (opts) {155		opts->retprobe = true;156		link2 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kretprobe_manual,157							      pattern, opts);158		if (!ASSERT_OK_PTR(link2, "bpf_program__attach_kprobe_multi_opts"))159			goto cleanup;160	}161 162	kprobe_multi_test_run(skel, !!opts);163 164cleanup:165	bpf_link__destroy(link2);166	bpf_link__destroy(link1);167	kprobe_multi__destroy(skel);168}169 170static void test_attach_api_pattern(void)171{172	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);173 174	test_attach_api("bpf_fentry_test*", &opts);175	test_attach_api("bpf_fentry_test?", NULL);176}177 178static void test_attach_api_addrs(void)179{180	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);181	unsigned long long addrs[8];182 183	GET_ADDR("bpf_fentry_test1", addrs[0]);184	GET_ADDR("bpf_fentry_test2", addrs[1]);185	GET_ADDR("bpf_fentry_test3", addrs[2]);186	GET_ADDR("bpf_fentry_test4", addrs[3]);187	GET_ADDR("bpf_fentry_test5", addrs[4]);188	GET_ADDR("bpf_fentry_test6", addrs[5]);189	GET_ADDR("bpf_fentry_test7", addrs[6]);190	GET_ADDR("bpf_fentry_test8", addrs[7]);191 192	opts.addrs = (const unsigned long *) addrs;193	opts.cnt = ARRAY_SIZE(addrs);194	test_attach_api(NULL, &opts);195}196 197static void test_attach_api_syms(void)198{199	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);200	const char *syms[8] = {201		"bpf_fentry_test1",202		"bpf_fentry_test2",203		"bpf_fentry_test3",204		"bpf_fentry_test4",205		"bpf_fentry_test5",206		"bpf_fentry_test6",207		"bpf_fentry_test7",208		"bpf_fentry_test8",209	};210 211	opts.syms = syms;212	opts.cnt = ARRAY_SIZE(syms);213	test_attach_api(NULL, &opts);214}215 216static void test_attach_api_fails(void)217{218	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);219	struct kprobe_multi *skel = NULL;220	struct bpf_link *link = NULL;221	unsigned long long addrs[2];222	const char *syms[2] = {223		"bpf_fentry_test1",224		"bpf_fentry_test2",225	};226	__u64 cookies[2];227	int saved_error;228 229	addrs[0] = ksym_get_addr("bpf_fentry_test1");230	addrs[1] = ksym_get_addr("bpf_fentry_test2");231 232	if (!ASSERT_FALSE(!addrs[0] || !addrs[1], "ksym_get_addr"))233		goto cleanup;234 235	skel = kprobe_multi__open_and_load();236	if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))237		goto cleanup;238 239	skel->bss->pid = getpid();240 241	/* fail_1 - pattern and opts NULL */242	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,243						     NULL, NULL);244	saved_error = -errno;245	if (!ASSERT_ERR_PTR(link, "fail_1"))246		goto cleanup;247 248	if (!ASSERT_EQ(saved_error, -EINVAL, "fail_1_error"))249		goto cleanup;250 251	/* fail_2 - both addrs and syms set */252	opts.addrs = (const unsigned long *) addrs;253	opts.syms = syms;254	opts.cnt = ARRAY_SIZE(syms);255	opts.cookies = NULL;256 257	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,258						     NULL, &opts);259	saved_error = -errno;260	if (!ASSERT_ERR_PTR(link, "fail_2"))261		goto cleanup;262 263	if (!ASSERT_EQ(saved_error, -EINVAL, "fail_2_error"))264		goto cleanup;265 266	/* fail_3 - pattern and addrs set */267	opts.addrs = (const unsigned long *) addrs;268	opts.syms = NULL;269	opts.cnt = ARRAY_SIZE(syms);270	opts.cookies = NULL;271 272	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,273						     "ksys_*", &opts);274	saved_error = -errno;275	if (!ASSERT_ERR_PTR(link, "fail_3"))276		goto cleanup;277 278	if (!ASSERT_EQ(saved_error, -EINVAL, "fail_3_error"))279		goto cleanup;280 281	/* fail_4 - pattern and cnt set */282	opts.addrs = NULL;283	opts.syms = NULL;284	opts.cnt = ARRAY_SIZE(syms);285	opts.cookies = NULL;286 287	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,288						     "ksys_*", &opts);289	saved_error = -errno;290	if (!ASSERT_ERR_PTR(link, "fail_4"))291		goto cleanup;292 293	if (!ASSERT_EQ(saved_error, -EINVAL, "fail_4_error"))294		goto cleanup;295 296	/* fail_5 - pattern and cookies */297	opts.addrs = NULL;298	opts.syms = NULL;299	opts.cnt = 0;300	opts.cookies = cookies;301 302	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,303						     "ksys_*", &opts);304	saved_error = -errno;305	if (!ASSERT_ERR_PTR(link, "fail_5"))306		goto cleanup;307 308	if (!ASSERT_EQ(saved_error, -EINVAL, "fail_5_error"))309		goto cleanup;310 311	/* fail_6 - abnormal cnt */312	opts.addrs = (const unsigned long *) addrs;313	opts.syms = NULL;314	opts.cnt = INT_MAX;315	opts.cookies = NULL;316 317	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,318						     NULL, &opts);319	saved_error = -errno;320	if (!ASSERT_ERR_PTR(link, "fail_6"))321		goto cleanup;322 323	if (!ASSERT_EQ(saved_error, -E2BIG, "fail_6_error"))324		goto cleanup;325 326cleanup:327	bpf_link__destroy(link);328	kprobe_multi__destroy(skel);329}330 331static void test_session_skel_api(void)332{333	struct kprobe_multi_session *skel = NULL;334	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);335	LIBBPF_OPTS(bpf_test_run_opts, topts);336	struct bpf_link *link = NULL;337	int i, err, prog_fd;338 339	skel = kprobe_multi_session__open_and_load();340	if (!ASSERT_OK_PTR(skel, "kprobe_multi_session__open_and_load"))341		return;342 343	skel->bss->pid = getpid();344 345	err = kprobe_multi_session__attach(skel);346	if (!ASSERT_OK(err, " kprobe_multi_session__attach"))347		goto cleanup;348 349	prog_fd = bpf_program__fd(skel->progs.trigger);350	err = bpf_prog_test_run_opts(prog_fd, &topts);351	ASSERT_OK(err, "test_run");352	ASSERT_EQ(topts.retval, 0, "test_run");353 354	/* bpf_fentry_test1-4 trigger return probe, result is 2 */355	for (i = 0; i < 4; i++)356		ASSERT_EQ(skel->bss->kprobe_session_result[i], 2, "kprobe_session_result");357 358	/* bpf_fentry_test5-8 trigger only entry probe, result is 1 */359	for (i = 4; i < 8; i++)360		ASSERT_EQ(skel->bss->kprobe_session_result[i], 1, "kprobe_session_result");361 362cleanup:363	bpf_link__destroy(link);364	kprobe_multi_session__destroy(skel);365}366 367static void test_session_cookie_skel_api(void)368{369	struct kprobe_multi_session_cookie *skel = NULL;370	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);371	LIBBPF_OPTS(bpf_test_run_opts, topts);372	struct bpf_link *link = NULL;373	int err, prog_fd;374 375	skel = kprobe_multi_session_cookie__open_and_load();376	if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))377		return;378 379	skel->bss->pid = getpid();380 381	err = kprobe_multi_session_cookie__attach(skel);382	if (!ASSERT_OK(err, " kprobe_multi_wrapper__attach"))383		goto cleanup;384 385	prog_fd = bpf_program__fd(skel->progs.trigger);386	err = bpf_prog_test_run_opts(prog_fd, &topts);387	ASSERT_OK(err, "test_run");388	ASSERT_EQ(topts.retval, 0, "test_run");389 390	ASSERT_EQ(skel->bss->test_kprobe_1_result, 1, "test_kprobe_1_result");391	ASSERT_EQ(skel->bss->test_kprobe_2_result, 2, "test_kprobe_2_result");392	ASSERT_EQ(skel->bss->test_kprobe_3_result, 3, "test_kprobe_3_result");393 394cleanup:395	bpf_link__destroy(link);396	kprobe_multi_session_cookie__destroy(skel);397}398 399static size_t symbol_hash(long key, void *ctx __maybe_unused)400{401	return str_hash((const char *) key);402}403 404static bool symbol_equal(long key1, long key2, void *ctx __maybe_unused)405{406	return strcmp((const char *) key1, (const char *) key2) == 0;407}408 409static bool is_invalid_entry(char *buf, bool kernel)410{411	if (kernel && strchr(buf, '['))412		return true;413	if (!kernel && !strchr(buf, '['))414		return true;415	return false;416}417 418static bool skip_entry(char *name)419{420	/*421	 * We attach to almost all kernel functions and some of them422	 * will cause 'suspicious RCU usage' when fprobe is attached423	 * to them. Filter out the current culprits - arch_cpu_idle424	 * default_idle and rcu_* functions.425	 */426	if (!strcmp(name, "arch_cpu_idle"))427		return true;428	if (!strcmp(name, "default_idle"))429		return true;430	if (!strncmp(name, "rcu_", 4))431		return true;432	if (!strcmp(name, "bpf_dispatcher_xdp_func"))433		return true;434	if (!strncmp(name, "__ftrace_invalid_address__",435		     sizeof("__ftrace_invalid_address__") - 1))436		return true;437	return false;438}439 440/* Do comparision by ignoring '.llvm.<hash>' suffixes. */441static int compare_name(const char *name1, const char *name2)442{443	const char *res1, *res2;444	int len1, len2;445 446	res1 = strstr(name1, ".llvm.");447	res2 = strstr(name2, ".llvm.");448	len1 = res1 ? res1 - name1 : strlen(name1);449	len2 = res2 ? res2 - name2 : strlen(name2);450 451	if (len1 == len2)452		return strncmp(name1, name2, len1);453	if (len1 < len2)454		return strncmp(name1, name2, len1) <= 0 ? -1 : 1;455	return strncmp(name1, name2, len2) >= 0 ? 1 : -1;456}457 458static int load_kallsyms_compare(const void *p1, const void *p2)459{460	return compare_name(((const struct ksym *)p1)->name, ((const struct ksym *)p2)->name);461}462 463static int search_kallsyms_compare(const void *p1, const struct ksym *p2)464{465	return compare_name(p1, p2->name);466}467 468static int get_syms(char ***symsp, size_t *cntp, bool kernel)469{470	size_t cap = 0, cnt = 0;471	char *name = NULL, *ksym_name, **syms = NULL;472	struct hashmap *map;473	struct ksyms *ksyms;474	struct ksym *ks;475	char buf[256];476	FILE *f;477	int err = 0;478 479	ksyms = load_kallsyms_custom_local(load_kallsyms_compare);480	if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_custom_local"))481		return -EINVAL;482 483	/*484	 * The available_filter_functions contains many duplicates,485	 * but other than that all symbols are usable in kprobe multi486	 * interface.487	 * Filtering out duplicates by using hashmap__add, which won't488	 * add existing entry.489	 */490 491	if (access("/sys/kernel/tracing/trace", F_OK) == 0)492		f = fopen("/sys/kernel/tracing/available_filter_functions", "r");493	else494		f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");495 496	if (!f)497		return -EINVAL;498 499	map = hashmap__new(symbol_hash, symbol_equal, NULL);500	if (IS_ERR(map)) {501		err = libbpf_get_error(map);502		goto error;503	}504 505	while (fgets(buf, sizeof(buf), f)) {506		if (is_invalid_entry(buf, kernel))507			continue;508 509		free(name);510		if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)511			continue;512		if (skip_entry(name))513			continue;514 515		ks = search_kallsyms_custom_local(ksyms, name, search_kallsyms_compare);516		if (!ks) {517			err = -EINVAL;518			goto error;519		}520 521		ksym_name = ks->name;522		err = hashmap__add(map, ksym_name, 0);523		if (err == -EEXIST) {524			err = 0;525			continue;526		}527		if (err)528			goto error;529 530		err = libbpf_ensure_mem((void **) &syms, &cap,531					sizeof(*syms), cnt + 1);532		if (err)533			goto error;534 535		syms[cnt++] = ksym_name;536	}537 538	*symsp = syms;539	*cntp = cnt;540 541error:542	free(name);543	fclose(f);544	hashmap__free(map);545	if (err)546		free(syms);547	return err;548}549 550static int get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel)551{552	unsigned long *addr, *addrs, *tmp_addrs;553	int err = 0, max_cnt, inc_cnt;554	char *name = NULL;555	size_t cnt = 0;556	char buf[256];557	FILE *f;558 559	if (access("/sys/kernel/tracing/trace", F_OK) == 0)560		f = fopen("/sys/kernel/tracing/available_filter_functions_addrs", "r");561	else562		f = fopen("/sys/kernel/debug/tracing/available_filter_functions_addrs", "r");563 564	if (!f)565		return -ENOENT;566 567	/* In my local setup, the number of entries is 50k+ so Let us initially568	 * allocate space to hold 64k entries. If 64k is not enough, incrementally569	 * increase 1k each time.570	 */571	max_cnt = 65536;572	inc_cnt = 1024;573	addrs = malloc(max_cnt * sizeof(long));574	if (addrs == NULL) {575		err = -ENOMEM;576		goto error;577	}578 579	while (fgets(buf, sizeof(buf), f)) {580		if (is_invalid_entry(buf, kernel))581			continue;582 583		free(name);584		if (sscanf(buf, "%p %ms$*[^\n]\n", &addr, &name) != 2)585			continue;586		if (skip_entry(name))587			continue;588 589		if (cnt == max_cnt) {590			max_cnt += inc_cnt;591			tmp_addrs = realloc(addrs, max_cnt);592			if (!tmp_addrs) {593				err = -ENOMEM;594				goto error;595			}596			addrs = tmp_addrs;597		}598 599		addrs[cnt++] = (unsigned long)addr;600	}601 602	*addrsp = addrs;603	*cntp = cnt;604 605error:606	free(name);607	fclose(f);608	if (err)609		free(addrs);610	return err;611}612 613static void do_bench_test(struct kprobe_multi_empty *skel, struct bpf_kprobe_multi_opts *opts)614{615	long attach_start_ns, attach_end_ns;616	long detach_start_ns, detach_end_ns;617	double attach_delta, detach_delta;618	struct bpf_link *link = NULL;619 620	attach_start_ns = get_time_ns();621	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_empty,622						     NULL, opts);623	attach_end_ns = get_time_ns();624 625	if (!ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts"))626		return;627 628	detach_start_ns = get_time_ns();629	bpf_link__destroy(link);630	detach_end_ns = get_time_ns();631 632	attach_delta = (attach_end_ns - attach_start_ns) / 1000000000.0;633	detach_delta = (detach_end_ns - detach_start_ns) / 1000000000.0;634 635	printf("%s: found %lu functions\n", __func__, opts->cnt);636	printf("%s: attached in %7.3lfs\n", __func__, attach_delta);637	printf("%s: detached in %7.3lfs\n", __func__, detach_delta);638}639 640static void test_kprobe_multi_bench_attach(bool kernel)641{642	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);643	struct kprobe_multi_empty *skel = NULL;644	char **syms = NULL;645	size_t cnt = 0;646 647	if (!ASSERT_OK(get_syms(&syms, &cnt, kernel), "get_syms"))648		return;649 650	skel = kprobe_multi_empty__open_and_load();651	if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))652		goto cleanup;653 654	opts.syms = (const char **) syms;655	opts.cnt = cnt;656 657	do_bench_test(skel, &opts);658 659cleanup:660	kprobe_multi_empty__destroy(skel);661	if (syms)662		free(syms);663}664 665static void test_kprobe_multi_bench_attach_addr(bool kernel)666{667	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);668	struct kprobe_multi_empty *skel = NULL;669	unsigned long *addrs = NULL;670	size_t cnt = 0;671	int err;672 673	err = get_addrs(&addrs, &cnt, kernel);674	if (err == -ENOENT) {675		test__skip();676		return;677	}678 679	if (!ASSERT_OK(err, "get_addrs"))680		return;681 682	skel = kprobe_multi_empty__open_and_load();683	if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))684		goto cleanup;685 686	opts.addrs = addrs;687	opts.cnt = cnt;688 689	do_bench_test(skel, &opts);690 691cleanup:692	kprobe_multi_empty__destroy(skel);693	free(addrs);694}695 696static void test_attach_override(void)697{698	struct kprobe_multi_override *skel = NULL;699	struct bpf_link *link = NULL;700 701	skel = kprobe_multi_override__open_and_load();702	if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))703		goto cleanup;704 705	/* The test_override calls bpf_override_return so it should fail706	 * to attach to bpf_fentry_test1 function, which is not on error707	 * injection list.708	 */709	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,710						     "bpf_fentry_test1", NULL);711	if (!ASSERT_ERR_PTR(link, "override_attached_bpf_fentry_test1")) {712		bpf_link__destroy(link);713		goto cleanup;714	}715 716	/* The should_fail_bio function is on error injection list,717	 * attach should succeed.718	 */719	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,720						     "should_fail_bio", NULL);721	if (!ASSERT_OK_PTR(link, "override_attached_should_fail_bio"))722		goto cleanup;723 724	bpf_link__destroy(link);725 726cleanup:727	kprobe_multi_override__destroy(skel);728}729 730void serial_test_kprobe_multi_bench_attach(void)731{732	if (test__start_subtest("kernel"))733		test_kprobe_multi_bench_attach(true);734	if (test__start_subtest("modules"))735		test_kprobe_multi_bench_attach(false);736	if (test__start_subtest("kernel"))737		test_kprobe_multi_bench_attach_addr(true);738	if (test__start_subtest("modules"))739		test_kprobe_multi_bench_attach_addr(false);740}741 742void test_kprobe_multi_test(void)743{744	if (!ASSERT_OK(load_kallsyms(), "load_kallsyms"))745		return;746 747	if (test__start_subtest("skel_api"))748		test_skel_api();749	if (test__start_subtest("link_api_addrs"))750		test_link_api_syms();751	if (test__start_subtest("link_api_syms"))752		test_link_api_addrs();753	if (test__start_subtest("attach_api_pattern"))754		test_attach_api_pattern();755	if (test__start_subtest("attach_api_addrs"))756		test_attach_api_addrs();757	if (test__start_subtest("attach_api_syms"))758		test_attach_api_syms();759	if (test__start_subtest("attach_api_fails"))760		test_attach_api_fails();761	if (test__start_subtest("attach_override"))762		test_attach_override();763	if (test__start_subtest("session"))764		test_session_skel_api();765	if (test__start_subtest("session_cookie"))766		test_session_cookie_skel_api();767}768